SystemVerilog probes · 105bVivado: supported
a 3-state enum FSM with a synchronous reset and no start value, read at the first clock edge before any reset (the board starts in IDLE and moves to RUN)
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 v2022.2 Ch.4 p.79: 'FDRE: D flip-flop with Clock Enable and Synchronous Reset', 'FDSE: D flip-flop with Clock Enable and Synchronous Set'; 'To initialize the content of a Register at circuit power-up, specify a default value for the signal during declaration'. What Vivado programs for a register WITHOUT a start value is not in the guide; the start values this row states are nextpnr-xilinx's def_init (xilinx/fasm.cc), checked on the product's own FASM
What does the open-source chain do with it?
every stage prints 'PASS': the rtl stage prints 'note [sim-starts-as-board]: 1 register without a start value starts as the board does, not at x: state at 0 (its reset value).' and the Makefile's FSM_KEEP_AWK sets fsm_encoding none on every named wire of the .il before synth_xilinx, so yosys keeps the student's 2-bit codes (bit prints 'pnr ok: 3 LUT, 2 FF', not the 3 one-hot FDRE of before) and the all-zero start the flip-flops get (#34) is IDLE, from which the netlist moves to RUN at the first edge as the RTL does ('EQV PASS: 262144 output bits compared, all equal'). Before #35 the rtl stage reported led=xxxxxxxxxxxxxxxx before the first edge (expected all off, IDLE) and the netlist stage led=0000000000000000 after the first edge with no reset pressed (expected all on, RUN): the one-hot register sat in no state. Vivado re-encodes by default (UG901 FSM_ENCODING, auto) and the guide does not say what the re-encoded register holds before its first reset
Which error pages explain the messages?
- sim-starts-as-board: Not an error: a register or a memory of the design has no start value, and the simulation starts it where the board starts it (the reset value; 0 without a reset; a LUT RAM word at 0) instead of x, so a case or an if that reads it before the first reset takes the same branch in the simulation and on the board.
What is the probe's code?
From test/sv/105b_fsm_first_edge.
design.sv
// a state machine with a synchronous reset and no start value, read at the first clock edge, before any reset:
// the board starts the register at its reset value (IDLE, code 0) and moves to RUN at the first edge
module top(input logic clk, input logic btnC, input logic [15:0] sw, output logic [15:0] led);
typedef enum logic [1:0] {IDLE, RUN, DONE} state_t;
state_t state, next;
always_ff @(posedge clk)
if (btnC) state <= IDLE;
else state <= next;
always_comb begin
next = state;
case (state)
IDLE: next = RUN;
RUN: next = DONE;
DONE: if (sw[0]) next = IDLE;
default: next = IDLE;
endcase
end
assign led = (state == RUN) ? 16'hFFFF : '0;
endmodule
tb.sv
// one clock edge with no reset: the board is in RUN (led all on); then reset and the usual run
module tb;
logic clk = 1'b0, btnC = 1'b0;
logic [15:0] sw = 16'h0001;
logic [15:0] led;
top dut(.clk(clk), .btnC(btnC), .sw(sw), .led(led));
task tick; begin #5 clk = 1'b1; #5 clk = 1'b0; end endtask
initial begin #200000 $display("FAIL: timeout"); $finish; end
initial begin
#1 if (led !== 16'h0000) begin $display("FAIL: before the first edge led=%b, expected all off (IDLE, the reset value the board starts in)", led); $finish; end
tick;
if (led !== 16'hFFFF) begin $display("FAIL: after the first edge, no reset pressed, led=%b, expected all on (RUN: the board starts in IDLE and moves on)", led); $finish; end
tick;
if (led !== 16'h0000) begin $display("FAIL: in DONE led=%b", led); $finish; end
btnC = 1'b1; tick; btnC = 1'b0;
if (led !== 16'h0000) begin $display("FAIL: after reset led=%b", led); $finish; end
tick;
if (led !== 16'hFFFF) begin $display("FAIL: RUN after reset led=%b", led); $finish; end
$display("PASS"); $finish;
end
endmodule
previous: four 4-bit registers read before the first clock edge: a synchronous reset to 5, an asynchronous reset to 4'b1010, no reset, a declared start value (logic [3:0] d = 4'd9)
next: a 4-word LUT RAM read before any write (mem[0] on the first edge)