SystemVerilog probes · 75Vivado: supported
a design that misses 100 MHz: a 14-bit value turned into four registered decimal digits (a long divide chain)
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 2015.2 implementation log of a public CS223 lab repo: routing ends at 'WNS=-20.758', then 'CRITICAL WARNING: [Timing 38-282] The design failed to meet the timing requirements.', 'Writing bitstream' and 'INFO: [Vivado 12-1842] Bitgen Completed Successfully.'; a timing failure is a critical warning in Vivado, not an error, and the .bit is in the run folder
What does the open-source chain do with it?
the netlist is right; the CLI stops with 'ERROR [timing-not-met]: timing not met: clk' (33.61 MHz with yosys 0.69+post, 33.91 MHz with 0.68) '(FAIL at 100.00 MHz). The longest path between two registers takes more than one period of that clock, so the design cannot run at it, and no bitstream is written; top.log has the critical path report (the registers and the logic between them). Fix: make the path shorter (a divide or a modulo in one cycle is the usual cause: register the intermediate results), or give it the time it needs: create_clock -period 30.000 [get_ports clk] (33.3 MHz) makes the check pass, and the Basys3 pin gives 100 MHz whatever the XDC says (its oscillator, Basys3 reference manual), so those registers must then take a new value only every 3 clocks or more (a clock enable from a counter: if (tick) ...).' (the recorded decision that a timing FAIL is an error; since #5 fix 3 the period it suggests is one the failing clock's number allows), where Vivado writes the bitstream with a critical warning
Which error pages explain the messages?
- 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/75_timing_not_met.
design.sv
module top(input logic clk, input logic btnC, input logic [15:0] sw, output logic [15:0] led);
logic [13:0] value;
logic [3:0] d0, d1, d2, d3;
always_ff @(posedge clk)
if (btnC) value <= sw[13:0]; // load a number with the center button
always_ff @(posedge clk) begin // its four decimal digits, registered: a long divide chain
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, 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 [13:0] v;
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));
// every 14-bit value: load it with btnC, one clock for the digits, then compare
initial begin
for (i = 0; i < 16384; i = i + 1) begin
v = i; sw = {~v[1:0], v}; btnC = 1'b1; tick; btnC = 1'b0; sw = ~sw; tick; #1
if (!(led === {4'(v / 1000), 4'((v / 100) % 10), 4'((v / 10) % 10), 4'(v % 10)})) begin $display("FAIL: decimal digits of %0d (led=%h)", v, led); $finish; end
end
$display("PASS"); $finish;
end
endmodule
previous: a .v design file with bit and final as names (keywords in SystemVerilog, names in Verilog 2005)
next: names the standard declares implicitly: a net from a port connection (.y(w)) and one from the left of an assign (assign eq = ...)