SystemVerilog probes · 80Vivado: unverified
an always_ff with an async reset and a statement after its if/else (d <= q; runs on the reset edge too)
Vivado: unverified. The open-source chain: it stops before a bitstream.
| stage | today |
|---|---|
| rtl, simulation | pass |
| synth, synthesis | fail |
| netlist, the netlist | not run |
| bit, the bitstream | fail |
What does Vivado do with it?
Unverified. UG901 v2023.2 Ch.5 'Flip-Flops, Registers, and Latches' (p.81-82) describes an asynchronous set/reset with the whole body under the reset's if/else; it does not say what Vivado does with a statement after it. No Vivado log of this case in the corpus (one lab folder has the pattern, without a log)
What does the open-source chain do with it?
since #5; rtl: PASS; yosys: 'ERROR: Async reset \btnC yields non-constant value', then the CLI names the block, the signal and the fix (before #5 only the yosys-slang line): "design.sv:3: ERROR [async-reset-nonconst]: this always_ff has an asynchronous reset (posedge btnC), so on btnC's edge every signal it writes must get a constant, and d does not:" 'Fix: make the reset if the whole block, with a constant for every signal in its first branch: if (btnC) begin q <= 0; d <= 0; end else begin q <= ...; d <= ...; end'; yosys-slang: 'design.sv:3:42: error: simple if-else pattern expected in modeling an asynchronous load on a flip-flop'
Which error pages explain the messages?
- async-reset-nonconst: In an always_ff with an asynchronous reset, the reset branch loads a register from a signal, or a signal is written outside the reset if/else; a flip-flop can only reset to a constant.
What is the probe's code?
From test/sv/80_async_reset_trailing.
design.sv
module top(input logic clk, input logic btnC, input logic [15:0] sw, output logic [15:0] led);
logic [3:0] q, d;
always_ff @(posedge clk, posedge btnC) begin
if (btnC) q <= 4'd0;
else q <= sw[3:0];
d <= q; // after the if/else: it runs on btnC's rising edge too
end
assign led = {8'd0, d, q};
endmodule
tb.sv
module tb;
reg clk = 1'b0;
reg btnC = 1'b0, btnU = 1'b0, btnD = 1'b0, btnL = 1'b0, btnR = 1'b0;
reg [15:0] sw = 16'h0000;
wire [15:0] led;
integer i; reg [3:0] q, d;
task tick; begin #5 clk = 1'b1; #5 clk = 1'b0; end endtask
initial begin #2000000 $display("FAIL: timeout"); $finish; end
top dut(.clk(clk), .btnC(btnC), .sw(sw), .led(led));
initial begin
#1 btnC = 1'b1; #1 btnC = 1'b0; q = 4'd0; d = 4'bx;
for (i = 0; i < 48; i = i + 1) begin
sw = {12'd0, 4'(i * 7 + 3)};
if (i % 4 == 3) begin #2 btnC = 1'b1; d = q; q = 4'd0; #1 btnC = 1'b0; end
else begin tick; d = q; q = sw[3:0]; end
#1 if (!(led === {8'd0, d, q})) begin $display("FAIL: step %0d (led=%h want %h%h)", i, led, d, q); $finish; end
end
$display("PASS"); $finish;
end
endmodule
previous: the same attribute written without spaces: (*keep_hierarchy="yes"*) (yosys keeps the submodule)
next: a design module that calls $finish in a simulation check (always @(posedge clk) if (...) $finish;), its submodule's ports named as the XDC's (counter.sv)