SystemVerilog probes · 89Vivado: supported

a clock divider's output clocks more logic than 100 MHz allows (four decimal digits of a 14-bit value on the slow clock); the XDC has no create_clock, as the course's master XDC arrives

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

stagetoday
rtl, simulationpass
synth, synthesispass
netlist, the netlistpass
bit, the bitstreamfail

What does Vivado do with it?

Supported. Vivado routed timing reports of CS223 labs in the corpus (11 runs, Vivado 2015.2 to 2021.2, each next to the .bit it wrote): a register clocked from another register is listed as 'There are N register/latch pins with no clock driven by root clock pin: <divider>/<its register>/Q (HIGH)' and is not timed; in the runs whose XDC has no create_clock the board clock is listed the same way ('... root clock pin: clk (HIGH)'), so nothing is timed

What does the open-source chain do with it?

dewfpga bit: "note [no-create-clock]: no create_clock in Basys3_Master.xdc; timing is checked against the Basys3's 100 MHz oscillator (--freq 100).", and every clock is checked at 100 MHz, the divided one too: 'ERROR [timing-not-met]: timing not met: clk' 'slow' '(FAIL at 100.00 MHz)', and since #5 the fix names the derived clock: 'slow is a clock made inside the design and is checked at the same 100 MHz, so clock those registers on the port clock with a clock enable (if (tick) ...) instead of on slow.' The slow clock reached about 35 MHz; it runs at 3.1 MHz here and at about 1 Hz in a lab. With create_clock uncommented nextpnr checks slow at its default 12 MHz and builds the breaker's version of this design (measured apart)

Which error pages explain the messages?

What is the probe's code?

From test/sv/89_clkdiv_slow_logic.

design.sv

module top(input logic clk, input logic btnC, input logic [15:0] sw, output logic [15:0] led);
  logic [3:0] div = '0;                   // a clock divider (a lab divides by 2^26; the width does not change the timing check)
  logic slow = 1'b0;
  always_ff @(posedge clk) begin div <= div + 4'd1; if (div == 4'd0) slow <= ~slow; end
  logic [13:0] value = '0;
  logic [3:0] d0 = '0, d1 = '0, d2 = '0, d3 = '0;
  always_ff @(posedge slow) if (btnC) value <= sw[13:0];
  always_ff @(posedge slow) begin         // the number's four decimal digits, on the slow clock
    d0 <= value % 10; d1 <= (value / 10) % 10; d2 <= (value / 100) % 10; d3 <= value / 1000;
  end
  assign led = {d3, d2, d1, d0};
endmodule

tb.sv

module tb;
  reg clk = 1'b0;
  reg btnC = 1'b0;
  reg [15:0] sw = 16'h0000;
  wire [15:0] led;
  task tick; begin #5 clk = 1'b1; #5 clk = 1'b0; end endtask
  initial begin #20000000 $display("FAIL: timeout"); $finish; end
  top dut(.clk(clk), .btnC(btnC), .sw(sw), .led(led));
  integer i, v; reg [15:0] want;
  // two edges of the slow clock (32 board clocks each): value loads on the first, the digits on the second
  task slow_edges; begin repeat (64) tick; end endtask
  initial begin
    for (i = 0; i < 300; i = i + 1) begin
      v = i == 0 ? 0 : i == 1 ? 9999 : i == 2 ? 16383 : i == 3 ? 1000 : $urandom % 16384;
      sw = v; btnC = 1; slow_edges; btnC = 0; slow_edges;
      want = {4'(v / 1000), 4'((v / 100) % 10), 4'((v / 10) % 10), 4'(v % 10)};
      if (led !== want) begin $display("FAIL: value %0d: led=%h, want %h", v, led, want); $finish; end
    end
    $display("PASS"); $finish;
  end
endmodule

previous: a class used for its static function, called as util::rev(sw[3:0]) (no object is made)
next: a parameter check in an initial block: initial if (N < 8) $warning(...)