Browse Source

Add simple VAI register file as base to try to formal verify FSM designs

T. Meissner 8 months ago
parent
commit
a0f6a0b81d
4 changed files with 355 additions and 0 deletions
  1. 6
    0
      vai_reg/Makefile
  2. 167
    0
      vai_reg/properties.sv
  3. 19
    0
      vai_reg/symbiyosys.sby
  4. 163
    0
      vai_reg/vai_reg.vhd

+ 6
- 0
vai_reg/Makefile View File

@@ -0,0 +1,6 @@
1
+vai_reg: vai_reg.vhd properties.sv symbiyosys.sby
2
+	sby -f -d work symbiyosys.sby
3
+
4
+
5
+clean:
6
+	rm -rf work

+ 167
- 0
vai_reg/properties.sv View File

@@ -0,0 +1,167 @@
1
+module properties (
2
+    input       Reset_n_i,
3
+    input       Clk_i,
4
+    input [7:0] Din_i,
5
+    input       DinValid_i,
6
+    input       DinStart_i,
7
+    input       DinStop_i,
8
+    input       DinAccept_o,
9
+    input [7:0] Dout_o,
10
+    input       DoutValid_o,
11
+    input       DoutStart_o,
12
+    input       DoutStop_o,
13
+    input       DoutAccept_i,
14
+    // Internals
15
+    input [2:0] s_fsm_state,
16
+    input [7:0] s_header
17
+);
18
+
19
+
20
+
21
+  `define READ 0
22
+  `define WRITE 1
23
+
24
+
25
+  reg init_state = 1;
26
+
27
+  // Initial reset
28
+  always @(*) begin
29
+    if (init_state) assume (!Reset_n_i);
30
+    if (!init_state) assume (Reset_n_i);
31
+  end
32
+
33
+  always @(posedge Clk_i)
34
+    init_state = 0;
35
+
36
+
37
+  // Constraints
38
+
39
+  assume property (@(posedge Clk_i)
40
+    DinValid_i && !DinAccept_o |=>
41
+    $stable(Din_i)
42
+  );
43
+
44
+  assume property (@(posedge Clk_i)
45
+    DinValid_i && !DinAccept_o |=>
46
+    $stable(DinStart_i)
47
+  );
48
+
49
+  assume property (@(posedge Clk_i)
50
+    DinValid_i && !DinAccept_o |=>
51
+    $stable(DinStop_i)
52
+  );
53
+
54
+
55
+  // Asserts
56
+
57
+  assert property (@(posedge Clk_i)
58
+    s_fsm_state >= 0 && s_fsm_state <= 6
59
+  );
60
+
61
+  assert property (@(posedge Clk_i)
62
+    DoutStart_o |->
63
+    DoutValid_o
64
+  );
65
+
66
+  assert property (@(posedge Clk_i)
67
+    DoutStart_o && DoutAccept_i |=>
68
+    !DoutStart_o
69
+  );
70
+
71
+  assert property (@(posedge Clk_i)
72
+    DoutStop_o |->
73
+    DoutValid_o
74
+  );
75
+
76
+  assert property (@(posedge Clk_i)
77
+    DoutStop_o && DoutAccept_i |=>
78
+    !DoutStop_o
79
+  );
80
+
81
+  assert property (@(posedge Clk_i)
82
+    s_fsm_state == 1 && DinValid_i && DinStart_i && DinAccept_o |=>
83
+    s_header == $past(Din_i)
84
+  );
85
+
86
+
87
+  // State changes
88
+
89
+  assert property (@(posedge Clk_i) disable iff (!Reset_n_i)
90
+    s_fsm_state == 0 |=> s_fsm_state == 1
91
+  );
92
+
93
+  assert property (@(posedge Clk_i) disable iff (!Reset_n_i)
94
+    s_fsm_state == 1 && DinValid_i && DinStart_i && DinStop_i && Din_i[3:0] == `READ |=>
95
+    s_fsm_state == 2
96
+  );
97
+
98
+  assert property (@(posedge Clk_i) disable iff (!Reset_n_i)
99
+    s_fsm_state == 1 && DinValid_i && DinStart_i && !DinStop_i && Din_i[3:0] == `WRITE |=>
100
+    s_fsm_state == 3
101
+  );
102
+
103
+  assert property (@(posedge Clk_i) disable iff (!Reset_n_i)
104
+    s_fsm_state == 2 |=> s_fsm_state == 4
105
+  );
106
+
107
+  assert property (@(posedge Clk_i) disable iff (!Reset_n_i)
108
+    s_fsm_state == 4 && DoutValid_o && DoutAccept_i && s_header[3:0] == `READ |=> s_fsm_state == 5
109
+  );
110
+
111
+  assert property (@(posedge Clk_i) disable iff (!Reset_n_i)
112
+    s_fsm_state == 4 && DoutValid_o && DoutAccept_i && s_header[3:0] != `READ |=> s_fsm_state == 6
113
+  );
114
+
115
+  assert property (@(posedge Clk_i) disable iff (!Reset_n_i)
116
+    s_fsm_state == 6 && DoutValid_o && DoutAccept_i |=> s_fsm_state == 0
117
+  );
118
+
119
+
120
+  // Protocol checks
121
+
122
+  assert property (@(posedge Clk_i)
123
+    s_fsm_state > 1 |->
124
+    s_header[3:0] == `READ || s_header[3:0] == `WRITE
125
+  );
126
+
127
+  assert property (@(posedge Clk_i)
128
+    DoutStart_o && DoutValid_o |->
129
+    Dout_o[3:0] == s_header[3:0]
130
+  );
131
+
132
+  assert property (@(posedge Clk_i)
133
+    DoutValid_o && !DoutAccept_i |=>
134
+    $stable(Dout_o)
135
+  );
136
+
137
+  assert property (@(posedge Clk_i)
138
+    DoutValid_o && !DoutAccept_i |=>
139
+    $stable(DoutStart_o)
140
+  );
141
+
142
+  assert property (@(posedge Clk_i)
143
+    DoutValid_o && !DoutAccept_i |=>
144
+    $stable(DoutStop_o)
145
+  );
146
+
147
+  assert property (@(posedge Clk_i)
148
+    DoutValid_o |-> !(DoutStart_o && DoutStop_o)
149
+  );
150
+
151
+  assert property (@(posedge Clk_i)
152
+    DoutStart_o |-> s_fsm_state == 4
153
+  );
154
+
155
+  assert property (@(posedge Clk_i)
156
+    DoutStop_o |-> s_fsm_state == 6
157
+  );
158
+
159
+  assert property (@(posedge Clk_i)
160
+    DoutValid_o |-> s_fsm_state >= 4 && s_fsm_state <= 6
161
+  );
162
+
163
+
164
+endmodule
165
+
166
+
167
+bind vai_reg properties properties (.*);

+ 19
- 0
vai_reg/symbiyosys.sby View File

@@ -0,0 +1,19 @@
1
+[options]
2
+depth 30
3
+wait on
4
+mode prove
5
+#mode bmc
6
+
7
+[engines]
8
+smtbmc
9
+#abc pdr
10
+
11
+[script]
12
+verific -vhdl vai_reg.vhd
13
+verific -formal properties.sv
14
+verific -import -extnets -all vai_reg
15
+prep -top vai_reg
16
+
17
+[files]
18
+vai_reg.vhd
19
+properties.sv

+ 163
- 0
vai_reg/vai_reg.vhd View File

@@ -0,0 +1,163 @@
1
+library ieee;
2
+use ieee.std_logic_1164.all;
3
+use ieee.numeric_std.all;
4
+
5
+
6
+
7
+entity vai_reg is
8
+  port (
9
+    Reset_n_i    : in  std_logic;
10
+    Clk_i        : in  std_logic;
11
+    -- req
12
+    Din_i        : in  std_logic_vector(7 downto 0);
13
+    DinValid_i   : in  std_logic;
14
+    DinStart_i   : in  std_logic;
15
+    DinStop_i    : in  std_logic;
16
+    DinAccept_o  : out std_logic;
17
+    -- ack
18
+    Dout_o       : out std_logic_vector(7 downto 0);
19
+    DoutValid_o  : out std_logic;
20
+    DoutStart_o  : out std_logic;
21
+    DoutStop_o   : out std_logic;
22
+    DoutAccept_i : in  std_logic
23
+  );
24
+end entity vai_reg;
25
+
26
+
27
+
28
+architecture rtl of vai_reg is
29
+
30
+
31
+  constant C_READ  : std_logic_vector(3 downto 0) := x"0";
32
+  constant C_WRITE : std_logic_vector(3 downto 0) := x"1";
33
+
34
+  type t_fsm_state is (IDLE, GET_HEADER, GET_DATA,
35
+                       SET_DATA, SEND_HEADER, SEND_DATA, SEND_FOOTER);
36
+  signal s_fsm_state : t_fsm_state;
37
+
38
+  type t_register is array(0 to 7) of std_logic_vector(7 downto 0);
39
+  signal s_register : t_register;
40
+
41
+  signal s_header : std_logic_vector(7 downto 0);
42
+  signal s_data   : std_logic_vector(7 downto 0);
43
+
44
+  signal s_error : boolean;
45
+
46
+  alias a_addr : std_logic_vector(3 downto 0) is s_header(7 downto 4);
47
+
48
+
49
+begin
50
+
51
+
52
+  process (Reset_n_i, Clk_i) is
53
+  begin
54
+    if (Reset_n_i = '0') then
55
+      DinAccept_o <= '0';
56
+      DoutStart_o <= '0';
57
+      DoutStop_o  <= '0';
58
+      DoutValid_o <= '0';
59
+      Dout_o      <= (others => '0');
60
+      s_header    <= (others => '0');
61
+      s_data      <= (others => '0');
62
+      s_register  <= (others => (others => '0'));
63
+      s_error     <= false;
64
+      s_fsm_state <= IDLE;
65
+    elsif (rising_edge(Clk_i)) then
66
+      case s_fsm_state is
67
+
68
+        when IDLE =>
69
+          DinAccept_o <= '0';
70
+          DoutStart_o <= '0';
71
+          DoutStop_o  <= '0';
72
+          DoutValid_o <= '0';
73
+          Dout_o      <= (others => '0');
74
+          s_header    <= (others => '0');
75
+          s_data      <= (others => '0');
76
+          s_error     <= false;
77
+          s_fsm_state <= GET_HEADER;
78
+
79
+        when GET_HEADER =>
80
+          DinAccept_o <= '1';
81
+          if (DinValid_i = '1' and DinStart_i = '1') then
82
+            DinAccept_o <= '0';
83
+            s_header    <= Din_i;
84
+            if (Din_i(3 downto 0) = C_READ and DinStop_i = '1') then
85
+              s_fsm_state <= GET_DATA;
86
+            elsif (Din_i(3 downto 0) = C_WRITE and DinStop_i = '0') then
87
+              s_fsm_state <= SET_DATA;
88
+            else
89
+              s_fsm_state <= IDLE;
90
+            end if;
91
+          end if;
92
+
93
+        when GET_DATA =>
94
+          if (unsigned(a_addr) <= 7) then
95
+            s_data <= s_register(to_integer(unsigned(a_addr)));
96
+          else
97
+            s_error <= true;
98
+            s_data  <= (others => '0');
99
+          end if;
100
+          s_fsm_state <= SEND_HEADER;
101
+
102
+        when SET_DATA =>
103
+          DinAccept_o <= '1';
104
+          if (DinValid_i = '1') then
105
+            DinAccept_o <= '0';
106
+            if (DinStop_i = '1') then
107
+              if (unsigned(a_addr) <= 7) then
108
+                -- Following line results in a Segmentation Fault
109
+                s_register(to_integer(unsigned(a_addr))) <= Din_i;
110
+                -- Following line results in following error:
111
+                -- ERROR: Unsupported cell type $dlatchsr for cell $verific$wide_dlatchrs_8.$verific$i1$172.
112
+                s_register(0) <= Din_i;
113
+              else
114
+                s_error <= true;
115
+              end if;
116
+              s_fsm_state <= SEND_HEADER;
117
+            else
118
+              s_fsm_state <= IDLE;
119
+            end if;
120
+          end if;
121
+
122
+        when SEND_HEADER =>
123
+          DoutValid_o <= '1';
124
+          DoutStart_o <= '1';
125
+          Dout_o      <= s_header;
126
+          if (DoutAccept_i = '1') then
127
+            DoutValid_o <= '0';
128
+            DoutStart_o <= '0';
129
+            if (s_header(3 downto 0) = C_WRITE) then
130
+              s_fsm_state <= SEND_FOOTER;
131
+            else
132
+              s_fsm_state <= SEND_DATA;
133
+            end if;
134
+          end if;
135
+
136
+        when SEND_DATA =>
137
+          DoutValid_o <= '1';
138
+          Dout_o      <= s_data;
139
+          if (DoutAccept_i = '1') then
140
+            DoutValid_o <= '0';
141
+            s_fsm_state <= SEND_FOOTER;
142
+          end if;
143
+
144
+        when SEND_FOOTER =>
145
+          DoutValid_o <= '1';
146
+          DoutStop_o  <= '1';
147
+          Dout_o      <= x"01" when s_error else x"00";
148
+          if (DoutAccept_i = '1') then
149
+            Dout_o      <= (others => '0');
150
+            DoutValid_o <= '0';
151
+            DoutStop_o  <= '0';
152
+            s_fsm_state <= IDLE;
153
+          end if;
154
+
155
+        when others => null;
156
+
157
+      end case;
158
+    end if;
159
+  end process;
160
+
161
+
162
+end architecture rtl;
163
+