SystemVerilog probes · 53Vivado: supported

async reset ORed with a synchronous clear: always_ff @(posedge clk, posedge btnC) if (btnC || btnU) q <= 0;

Vivado: supported. The open-source chain: it stops before a bitstream.

stagetoday
rtl, simulationpass
synth, synthesisfail
netlist, the netlistnot run
bit, the bitstreamfail

What does Vivado do with it?

Supported. Vivado 2021.2 logs of a public lab repo (CS-224, the course after CS223): an always_ff @(posedge clk, posedge reset) whose first branch is if (reset || clear): 'INFO: [Synth 8-6155] done synthesizing module '<that module>' (13#1)', 'Synthesis finished with 0 errors, 0 critical warnings and 2 warnings.'; implementation 'write_bitstream completed successfully'

What does the open-source chain do with it?

since #5; rtl: PASS; yosys: 'ERROR: Multiple edge sensitive events found for this signal!', then the CLI names the block and the real cause (before #5 it said two always blocks): 'design.sv:3: ERROR [async-reset-not-alone]: this always block is sensitive to two edges (@(posedge clk, posedge btnC)), so one of them is an asynchronous reset, but its first if does not test that reset alone (a reset ORed with a synchronous clear: if (rst || clear)), so neither reader can tell the reset from the clock. Fix: test the reset alone first and put the synchronous clear in the else: if (btnC) q <= 0; else if (clear) q <= 0; else q <= q + 1;'; yosys-slang: 'design.sv:4:5: error: condition cannot be matched to any signal from the event list'

Which error pages explain the messages?

What is the probe's code?

From test/sv/53_async_reset_sync_clear.

design.sv

module top(input logic clk, input logic btnC, input logic btnU, output logic [15:0] led);
  logic [3:0] q;
  always_ff @(posedge clk, posedge btnC)   // btnC: asynchronous reset
    if (btnC || btnU) q <= 4'd0;         // btnU: a synchronous clear, in the same branch
    else              q <= q + 4'd1;
  assign led = {12'd0, q};
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
  top dut(.clk(clk), .btnC(btnC), .btnU(btnU), .led(led));
  initial begin
    #1 btnC = 1; #1 btnC = 0; #1
    if (!(led === 16'd0)) begin $display("FAIL: async reset without a clock edge (led=%h)", led); $finish; end
    tick; tick; tick;
    if (!(led === 16'd3)) begin $display("FAIL: counts 3 (led=%h)", led); $finish; end
    btnU = 1; #1
    if (!(led === 16'd3)) begin $display("FAIL: btnU waits for the clock (led=%h)", led); $finish; end
    tick; btnU = 0;
    if (!(led === 16'd0)) begin $display("FAIL: btnU clears on the edge (led=%h)", led); $finish; end
    tick; tick; #2 btnC = 1; #1
    if (!(led === 16'd0)) begin $display("FAIL: async reset mid-cycle (led=%h)", led); $finish; end
    btnC = 0; tick;
    if (!(led === 16'd1)) begin $display("FAIL: counts again (led=%h)", led); $finish; end
    $display("PASS"); $finish;
  end
endmodule

previous: an internal tri bus with two tristate drivers taking turns (the textbook's mux from tristate buffers)
next: a name used before its declaration: assign led[0] = stop; logic stop;