SystemVerilog probes · 94Vivado: supported
a variable raised to a constant power: assign led = sw[7:0] ** 2;
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. UG901 v2023.2 Ch.10 'Operators' (p.278): 'Note: A**B is supported if A is a power of 2 or B is a constant.' (Ch.9 Table 25, p.249, lists Power with both operands constant, or with a first operand of 2 and a variable second)
What does the open-source chain do with it?
yosys leaves the $pow cell of a variable base unmapped: the netlist is right, and nextpnr stops with 'no Bels remaining of type '$pow'', which since #5 the CLI reads as 'design.sv:3: ERROR [power-operator]: ** with a base that is a signal (sw ** 2): yosys builds ** only for a constant base and exponent, or 2 ** n, and leaves this one as a $pow cell nextpnr has nothing to place on. Not a size problem. Fix: write the multiplication out (sw * sw), a table (case), or 1 << n for a power of two.' (before #5: the design does not fit the XC7A35T, for one square). 16'd3 ** sw[2:0], which UG901's note does not cover, stops the same way; 2 ** sw[3:0] and sw[7:0] * sw[7:0] build (measured apart)
Which error pages explain the messages?
- power-operator: The ** operator with a variable base; yosys builds only constant powers and 2 ** n.
What is the probe's code?
From test/sv/94_power_var_base.
design.sv
// the square of the switches: a variable raised to a constant power
module top(input logic [15:0] sw, output logic [15:0] led);
assign led = sw[7:0] ** 2;
endmodule
tb.sv
module tb;
logic [15:0] sw = 0; logic [15:0] led;
top dut(.sw(sw), .led(led));
integer i, bad = 0;
initial begin
for (i = 0; i < 512; i++) begin
sw = {i[0] ? 8'hff : 8'h00, i[8:1]}; // every value of sw[7:0], with sw[15:8] low and high
#1 if (led !== 16'(i[8:1] * i[8:1])) begin bad++; if (bad < 4) $display("FAIL: sw=%h led=%0d want %0d", sw, led, i[8:1] * i[8:1]); end
end
if (bad == 0) $display("PASS"); else $display("FAIL: %0d of 512", bad);
$finish;
end
endmodule
previous: two modules nothing instantiates, in one file named after one of them (counter.sv: the plain counter, and the board version the project names as its top)
next: a submodule declared with its ports and no body (a lab part not written yet), its output used by top