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.
| stage | today |
|---|---|
| rtl, simulation | pass |
| synth, synthesis | pass |
| netlist, the netlist | pass |
| bit, the bitstream | fail |
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?
- no-create-clock: Not an error: the XDC has no create_clock line, so every clock is checked at the board's 100 MHz.
- timing-not-met: The longest path between two registers is longer than the clock period; the CLI writes no bitstream where Vivado would, with a critical warning.
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(...)