SystemVerilog probes · 55Vivado: unverified
a conditional between two values of one enum: next = sw[0] ? RUN : IDLE;
Vivado: unverified. 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?
Unverified. UG901 v2023.2 does not say what Vivado does with a conditional whose two values are of one enum type (Table 27 (p.285) lists 'Type checking' and 'Enumerated types in numerical expressions' as Supported, neither about this). No Vivado log of this case in the corpus. slang, a strict IEEE 1800 frontend, accepts it
What does the open-source chain do with it?
since #28 rtl: PASS: iverilog refuses the design, 'design.sv:7: error: This assignment requires an explicit cast.', and dewfpga sim goes on with 'design.sv:7: 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: 'This assignment requires an explicit cast.' (design.sv:7), no fix offered; 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/55_enum_conditional.
design.sv
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
case (state)
IDLE: next = sw[0] ? RUN : IDLE; // a conditional between two values of one enum
RUN: next = sw[1] ? DONE : RUN;
default: next = sw[2] ? IDLE : DONE;
endcase
assign led = {14'b0, state};
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; wire [6:0] seg; wire dp; wire [3:0] an;
task tick; begin #5 clk = 1'b1; #5 clk = 1'b0; end endtask
initial begin #200000 $display("FAIL: timeout"); $finish; end
integer s, v; reg [1:0] want;
top dut(.clk(clk), .btnC(btnC), .sw(sw), .led(led));
// from reset to state s: IDLE, then RUN with sw[0] up, then DONE with sw[1] up
task goto(input integer s); begin
btnC = 1'b1; sw = 16'h0000; tick; btnC = 1'b0;
if (s >= 1) begin sw = 16'h0001; tick; end
if (s >= 2) begin sw = 16'h0002; tick; end
if (!(led === {14'd0, s[1:0]})) begin $display("FAIL: reach state %0d (led=%h)", s, led); $finish; end
end endtask
initial begin
// every reachable state, with every value of sw[2:0] and btnC (the other switches vary too)
for (s = 0; s < 3; s = s + 1)
for (v = 0; v < 16; v = v + 1) begin
goto(s);
sw = {13'(v * 16'h2b9 + s * 16'h1c3), v[2:0]}; btnC = v[3]; tick; btnC = 1'b0;
want = v[3] ? 2'd0 : (s == 0) ? (v[0] ? 2'd1 : 2'd0) : (s == 1) ? (v[1] ? 2'd2 : 2'd1) : (v[2] ? 2'd0 : 2'd2);
if (!(led === {14'd0, want})) begin $display("FAIL: state %0d, sw[2:0]=%b, btnC=%b: next %0d (led=%h)", s, v[2:0], v[3], want, led); $finish; end
end
$display("PASS"); $finish;
end
endmodule
previous: a name used before its declaration: assign led[0] = stop; logic stop;
next: typedef enum {S0, S1, S2} outside the module (compilation-unit scope), with the textbook's state names