SystemVerilog probes · 13dVivado: supported
a packed 2-D array indexed by a variable, then a bit or part select: grid[i][j] <= ... in a loop, grid[sw[13:12]][3:1]
Vivado: supported. The open-source chain: all four stages pass.
| stage | today |
|---|---|
| rtl, simulation | pass |
| synth, synthesis | pass |
| netlist, the netlist | pass |
| bit, the bitstream | pass |
What does Vivado do with it?
Supported. UG901 v2023.2 Ch.10 Table 27 (p.285): 'Packed arrays', 'Multidimensional arrays', 'Indexing and slicing of arrays': Supported. Vivado 2019.1 logs of a public CS223 course project: a logic [7:0][7:0] array written and read with two loop indices, [i][j], 'Synthesis finished with 0 errors, 0 critical warnings and 0 warnings.', implementation 'write_bitstream completed successfully'
What does the open-source chain do with it?
since #28 rtl: PASS: iverilog refuses the design, 'design.sv:8: error: A reference to a net or variable', and dewfpga sim goes on with 'design.sv:8: note [sim-from-build]' (the simulation runs on the design as the build reads it, read by yosys' own reader, written back as Verilog and compiled with the testbench and yosys' cell models), then 'PASS'; iverilog 13 alone: 'Array index expressions must be constant here.' at the write in the loop (design.sv:6) and at both reads (design.sv:8, design.sv:9); yosys builds it; netlist: testbench only, eqv.sh cannot compile the RTL with iverilog
Which error pages explain the messages?
- sim-from-build: Not an error: iverilog refused a construct in the design, so the testbench ran against the design as the build elaborates it, read by the reader the note names.
What is the probe's code?
From test/sv/13d_packed_2d_var_index.
design.sv
module top(input logic clk, input logic [15:0] sw, output logic [15:0] led);
logic [3:0][3:0] grid; // a 4x4 LED matrix, one packed 2-D array
always_ff @(posedge clk)
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
grid[i][j] <= sw[4*i + j]; // a variable index, then a bit select
assign led[11:0] = grid[2:0];
assign led[12] = grid[sw[13:12]][sw[15:14]]; // one cell, picked by four switches
assign led[15:13] = grid[sw[13:12]][3:1]; // part of the row two switches pick
endmodule
tb.sv
module tb;
// iverilog cannot compile this design, so the netlist has only this testbench to catch a synthesis fault
// (eqv.sh skips): the grid is clocked in from one value of the switches, and the row and column that
// led[15:12] pick come from another, so every LUT input combination shows, not only grid == sw
logic clk = 0; logic [15:0] sw = 0; logic [15:0] led;
top dut(.clk(clk), .sw(sw), .led(led));
integer i, bad = 0; logic [15:0] g, want;
initial begin
for (i = 0; i < 20000; i++) begin
sw = (i < 256) ? {i[7:0], i[7:0]} : $random;
#5 clk = 1; #5 clk = 0; g = sw; // what grid holds now
if (i >= 256) begin sw = $random; #1; end // a new row and column, the grid unchanged
want[11:0] = g[11:0];
want[12] = g[4*sw[13:12] + sw[15:14]];
want[15:13] = g[4*sw[13:12] + 1 +: 3];
if (led !== want) begin bad++; if (bad < 4) $display("FAIL: grid=%h sw=%h led=%h want=%h", g, sw, led, want); end
end
if (bad == 0) $display("PASS"); else $display("FAIL: %0d of 20000", bad);
$finish;
end
endmodule
previous: an unpacked array concatenation: assign arr = {sw[3:0], sw[7:4]}; to logic [3:0] arr [0:1]
next: typed parameters, one depending on another, localparam, #(.W(8),.K(3)) and positional #(4)