SystemVerilog probes · 81Vivado: supported

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)

Vivado: supported. The open-source chain: it stops before a bitstream.

stagetoday
rtl, simulationfail
synth, synthesisfail
netlist, the netlistnot run
bit, the bitstreamfail

What does Vivado do with it?

Supported. UG901 v2023.2 Ch.9 Table 21 (p.239): '$finish: Ignored' (p.240: '$stop: Ignored'), and 'Vivado synthesis ignores unsupported system tasks.'

What does the open-source chain do with it?

a module with ports is a design even when it calls $finish, and the $finish is the student's mistake: dewfpga sim and dewfpga bit both stop before make with 'design.sv:6: ERROR [finish-in-design]: $finish in a design module (top): Vivado ignores it (UG901 Table 21: $finish Ignored) and yosys stops on it. Fix: remove it, move the check to the testbench, or wrap it in' an ifndef SYNTHESIS block; no counter.bit, no top.bit. The same $finish under `ifndef SYNTHESIS is not reported: yosys' preprocessor drops that block, as Vivado's does (UG901). Vivado ignores $finish and builds it: a gap, no longer a silent wrong

Which error pages explain the messages?

What is the probe's code?

From test/sv/81_finish_in_design.

design.sv

module top(input logic clk, input logic btnC, input logic [15:0] sw, output logic [15:0] led);
  logic [15:0] cnt;
  counter u_c (.clk(clk), .btnC(btnC), .led(cnt));
  assign led = sw[15] ? sw : cnt;
  // a check for the simulation; synthesis ignores $finish (UG901 Table 21)
  always @(posedge clk) if (cnt == 16'hFFFF) begin $display("ERROR: the counter wrapped"); $finish; end
endmodule

counter.sv

module counter(input logic clk, input logic btnC, output logic [15:0] led);   // its ports have the XDC's names
  always_ff @(posedge clk) if (btnC) led <= '0; else led <= led + 16'd1;
endmodule

tb.sv

module tb;
  reg clk = 1'b0, btnC = 1'b0;
  reg [15:0] sw = 16'h0000;
  wire [15:0] led;
  reg [15:0] want;
  integer i;
  top dut(.clk(clk), .btnC(btnC), .sw(sw), .led(led));
  task tick; begin #5 clk = 1'b1; #5 clk = 1'b0; end endtask
  initial begin
    btnC = 1'b1; tick; btnC = 1'b0; want = 16'd0;
    for (i = 0; i < 40; i = i + 1) begin
      sw = {i[0], 15'h1234 ^ i[14:0]}; #1
      if (!(led === (sw[15] ? sw : want))) begin $display("FAIL: the counter or the switch mux (i=%0d led=%h)", i, led); $finish; end
      tick; want = want + 16'd1;
    end
    $display("PASS"); $finish;
  end
endmodule

previous: an always_ff with an async reset and a statement after its if/else (d <= q; runs on the reset edge too)
next: file tasks left in a design module: $fopen, $fdisplay and $fwrite (a debug trace)