aboutsummaryrefslogtreecommitdiff
path: root/verif/formal/simple_alu/simple_alu_fv.sv
blob: ea9700a6810b01b1438d98600fc5c744fab462f3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// Formal verification module for simple_alu.
// All ports are inputs - this module only observes DUT signals, never drives them.
// Instantiated via simple_alu_top_fv.sv wrapper (bind unsupported in open-source Yosys).
module simple_alu_fv (
    input logic        clk,
    input logic [31:0] a,
    input logic [31:0] b,
    input logic        sel,
    input logic        rst,

    input logic [31:0] y,
    input logic        overflow
  );

    // -------------------------------------------------------------------------
    // Initial assumptions - constrain starting state so solver doesn't
    // explore garbage initial register values
    // -------------------------------------------------------------------------
    initial assume(~rst);
    initial assume(y == '0);
    initial assume(overflow == 1'b0);

    //assertion check: if rst deasserted, y tied to 0
    //assertions are what we want to prove, formal verification is the engine that proves it
    // property p_rst_y;          
    //     @(posedge clk)
    //     ~rst |=> (y=='0);      
    // endproperty
    // a_rst_y: assert property (p_rst_y)
    //     else $error("RESET CHECK FAILED: rst=%0b y=%0h, expected y=0", rst, y);

    // Reset check - y must be 0 one cycle after reset asserts (active low)
    always @(posedge clk) begin
        if ( $past(~rst)) begin
            assert (y == '0);
            assert (overflow == 0);
        end
    end

    // -------------------------------------------------------------------------
    // Cover statements - solver finds shortest path to reach each state
    // These generate VCD traces you can inspect in GTKWave
    // -------------------------------------------------------------------------

    always @(posedge clk) begin      
        cover ($past(sel == 0) && overflow == 1'b1);  // addition overflow
        cover ($past(sel == 1) && overflow == 1'b1);  // subtraction underflow  
    end


endmodule