| @ -0,0 +1,6 @@ | |||
| vai_reg: vai_reg.vhd properties.sv symbiyosys.sby | |||
| sby -f -d work symbiyosys.sby | |||
| clean: | |||
| rm -rf work | |||
| @ -0,0 +1,167 @@ | |||
| module properties ( | |||
| input Reset_n_i, | |||
| input Clk_i, | |||
| input [7:0] Din_i, | |||
| input DinValid_i, | |||
| input DinStart_i, | |||
| input DinStop_i, | |||
| input DinAccept_o, | |||
| input [7:0] Dout_o, | |||
| input DoutValid_o, | |||
| input DoutStart_o, | |||
| input DoutStop_o, | |||
| input DoutAccept_i, | |||
| // Internals | |||
| input [2:0] s_fsm_state, | |||
| input [7:0] s_header | |||
| ); | |||
| `define READ 0 | |||
| `define WRITE 1 | |||
| reg init_state = 1; | |||
| // Initial reset | |||
| always @(*) begin | |||
| if (init_state) assume (!Reset_n_i); | |||
| if (!init_state) assume (Reset_n_i); | |||
| end | |||
| always @(posedge Clk_i) | |||
| init_state = 0; | |||
| // Constraints | |||
| assume property (@(posedge Clk_i) | |||
| DinValid_i && !DinAccept_o |=> | |||
| $stable(Din_i) | |||
| ); | |||
| assume property (@(posedge Clk_i) | |||
| DinValid_i && !DinAccept_o |=> | |||
| $stable(DinStart_i) | |||
| ); | |||
| assume property (@(posedge Clk_i) | |||
| DinValid_i && !DinAccept_o |=> | |||
| $stable(DinStop_i) | |||
| ); | |||
| // Asserts | |||
| assert property (@(posedge Clk_i) | |||
| s_fsm_state >= 0 && s_fsm_state <= 6 | |||
| ); | |||
| assert property (@(posedge Clk_i) | |||
| DoutStart_o |-> | |||
| DoutValid_o | |||
| ); | |||
| assert property (@(posedge Clk_i) | |||
| DoutStart_o && DoutAccept_i |=> | |||
| !DoutStart_o | |||
| ); | |||
| assert property (@(posedge Clk_i) | |||
| DoutStop_o |-> | |||
| DoutValid_o | |||
| ); | |||
| assert property (@(posedge Clk_i) | |||
| DoutStop_o && DoutAccept_i |=> | |||
| !DoutStop_o | |||
| ); | |||
| assert property (@(posedge Clk_i) | |||
| s_fsm_state == 1 && DinValid_i && DinStart_i && DinAccept_o |=> | |||
| s_header == $past(Din_i) | |||
| ); | |||
| // State changes | |||
| assert property (@(posedge Clk_i) disable iff (!Reset_n_i) | |||
| s_fsm_state == 0 |=> s_fsm_state == 1 | |||
| ); | |||
| assert property (@(posedge Clk_i) disable iff (!Reset_n_i) | |||
| s_fsm_state == 1 && DinValid_i && DinStart_i && DinStop_i && Din_i[3:0] == `READ |=> | |||
| s_fsm_state == 2 | |||
| ); | |||
| assert property (@(posedge Clk_i) disable iff (!Reset_n_i) | |||
| s_fsm_state == 1 && DinValid_i && DinStart_i && !DinStop_i && Din_i[3:0] == `WRITE |=> | |||
| s_fsm_state == 3 | |||
| ); | |||
| assert property (@(posedge Clk_i) disable iff (!Reset_n_i) | |||
| s_fsm_state == 2 |=> s_fsm_state == 4 | |||
| ); | |||
| assert property (@(posedge Clk_i) disable iff (!Reset_n_i) | |||
| s_fsm_state == 4 && DoutValid_o && DoutAccept_i && s_header[3:0] == `READ |=> s_fsm_state == 5 | |||
| ); | |||
| assert property (@(posedge Clk_i) disable iff (!Reset_n_i) | |||
| s_fsm_state == 4 && DoutValid_o && DoutAccept_i && s_header[3:0] != `READ |=> s_fsm_state == 6 | |||
| ); | |||
| assert property (@(posedge Clk_i) disable iff (!Reset_n_i) | |||
| s_fsm_state == 6 && DoutValid_o && DoutAccept_i |=> s_fsm_state == 0 | |||
| ); | |||
| // Protocol checks | |||
| assert property (@(posedge Clk_i) | |||
| s_fsm_state > 1 |-> | |||
| s_header[3:0] == `READ || s_header[3:0] == `WRITE | |||
| ); | |||
| assert property (@(posedge Clk_i) | |||
| DoutStart_o && DoutValid_o |-> | |||
| Dout_o[3:0] == s_header[3:0] | |||
| ); | |||
| assert property (@(posedge Clk_i) | |||
| DoutValid_o && !DoutAccept_i |=> | |||
| $stable(Dout_o) | |||
| ); | |||
| assert property (@(posedge Clk_i) | |||
| DoutValid_o && !DoutAccept_i |=> | |||
| $stable(DoutStart_o) | |||
| ); | |||
| assert property (@(posedge Clk_i) | |||
| DoutValid_o && !DoutAccept_i |=> | |||
| $stable(DoutStop_o) | |||
| ); | |||
| assert property (@(posedge Clk_i) | |||
| DoutValid_o |-> !(DoutStart_o && DoutStop_o) | |||
| ); | |||
| assert property (@(posedge Clk_i) | |||
| DoutStart_o |-> s_fsm_state == 4 | |||
| ); | |||
| assert property (@(posedge Clk_i) | |||
| DoutStop_o |-> s_fsm_state == 6 | |||
| ); | |||
| assert property (@(posedge Clk_i) | |||
| DoutValid_o |-> s_fsm_state >= 4 && s_fsm_state <= 6 | |||
| ); | |||
| endmodule | |||
| bind vai_reg properties properties (.*); | |||
| @ -0,0 +1,19 @@ | |||
| [options] | |||
| depth 30 | |||
| wait on | |||
| mode prove | |||
| #mode bmc | |||
| [engines] | |||
| smtbmc | |||
| #abc pdr | |||
| [script] | |||
| verific -vhdl vai_reg.vhd | |||
| verific -formal properties.sv | |||
| verific -import -extnets -all vai_reg | |||
| prep -top vai_reg | |||
| [files] | |||
| vai_reg.vhd | |||
| properties.sv | |||
| @ -0,0 +1,163 @@ | |||
| library ieee; | |||
| use ieee.std_logic_1164.all; | |||
| use ieee.numeric_std.all; | |||
| entity vai_reg is | |||
| port ( | |||
| Reset_n_i : in std_logic; | |||
| Clk_i : in std_logic; | |||
| -- req | |||
| Din_i : in std_logic_vector(7 downto 0); | |||
| DinValid_i : in std_logic; | |||
| DinStart_i : in std_logic; | |||
| DinStop_i : in std_logic; | |||
| DinAccept_o : out std_logic; | |||
| -- ack | |||
| Dout_o : out std_logic_vector(7 downto 0); | |||
| DoutValid_o : out std_logic; | |||
| DoutStart_o : out std_logic; | |||
| DoutStop_o : out std_logic; | |||
| DoutAccept_i : in std_logic | |||
| ); | |||
| end entity vai_reg; | |||
| architecture rtl of vai_reg is | |||
| constant C_READ : std_logic_vector(3 downto 0) := x"0"; | |||
| constant C_WRITE : std_logic_vector(3 downto 0) := x"1"; | |||
| type t_fsm_state is (IDLE, GET_HEADER, GET_DATA, | |||
| SET_DATA, SEND_HEADER, SEND_DATA, SEND_FOOTER); | |||
| signal s_fsm_state : t_fsm_state; | |||
| type t_register is array(0 to 7) of std_logic_vector(7 downto 0); | |||
| signal s_register : t_register; | |||
| signal s_header : std_logic_vector(7 downto 0); | |||
| signal s_data : std_logic_vector(7 downto 0); | |||
| signal s_error : boolean; | |||
| alias a_addr : std_logic_vector(3 downto 0) is s_header(7 downto 4); | |||
| begin | |||
| process (Reset_n_i, Clk_i) is | |||
| begin | |||
| if (Reset_n_i = '0') then | |||
| DinAccept_o <= '0'; | |||
| DoutStart_o <= '0'; | |||
| DoutStop_o <= '0'; | |||
| DoutValid_o <= '0'; | |||
| Dout_o <= (others => '0'); | |||
| s_header <= (others => '0'); | |||
| s_data <= (others => '0'); | |||
| s_register <= (others => (others => '0')); | |||
| s_error <= false; | |||
| s_fsm_state <= IDLE; | |||
| elsif (rising_edge(Clk_i)) then | |||
| case s_fsm_state is | |||
| when IDLE => | |||
| DinAccept_o <= '0'; | |||
| DoutStart_o <= '0'; | |||
| DoutStop_o <= '0'; | |||
| DoutValid_o <= '0'; | |||
| Dout_o <= (others => '0'); | |||
| s_header <= (others => '0'); | |||
| s_data <= (others => '0'); | |||
| s_error <= false; | |||
| s_fsm_state <= GET_HEADER; | |||
| when GET_HEADER => | |||
| DinAccept_o <= '1'; | |||
| if (DinValid_i = '1' and DinStart_i = '1') then | |||
| DinAccept_o <= '0'; | |||
| s_header <= Din_i; | |||
| if (Din_i(3 downto 0) = C_READ and DinStop_i = '1') then | |||
| s_fsm_state <= GET_DATA; | |||
| elsif (Din_i(3 downto 0) = C_WRITE and DinStop_i = '0') then | |||
| s_fsm_state <= SET_DATA; | |||
| else | |||
| s_fsm_state <= IDLE; | |||
| end if; | |||
| end if; | |||
| when GET_DATA => | |||
| if (unsigned(a_addr) <= 7) then | |||
| s_data <= s_register(to_integer(unsigned(a_addr))); | |||
| else | |||
| s_error <= true; | |||
| s_data <= (others => '0'); | |||
| end if; | |||
| s_fsm_state <= SEND_HEADER; | |||
| when SET_DATA => | |||
| DinAccept_o <= '1'; | |||
| if (DinValid_i = '1') then | |||
| DinAccept_o <= '0'; | |||
| if (DinStop_i = '1') then | |||
| if (unsigned(a_addr) <= 7) then | |||
| -- Following line results in a Segmentation Fault | |||
| s_register(to_integer(unsigned(a_addr))) <= Din_i; | |||
| -- Following line results in following error: | |||
| -- ERROR: Unsupported cell type $dlatchsr for cell $verific$wide_dlatchrs_8.$verific$i1$172. | |||
| s_register(0) <= Din_i; | |||
| else | |||
| s_error <= true; | |||
| end if; | |||
| s_fsm_state <= SEND_HEADER; | |||
| else | |||
| s_fsm_state <= IDLE; | |||
| end if; | |||
| end if; | |||
| when SEND_HEADER => | |||
| DoutValid_o <= '1'; | |||
| DoutStart_o <= '1'; | |||
| Dout_o <= s_header; | |||
| if (DoutAccept_i = '1') then | |||
| DoutValid_o <= '0'; | |||
| DoutStart_o <= '0'; | |||
| if (s_header(3 downto 0) = C_WRITE) then | |||
| s_fsm_state <= SEND_FOOTER; | |||
| else | |||
| s_fsm_state <= SEND_DATA; | |||
| end if; | |||
| end if; | |||
| when SEND_DATA => | |||
| DoutValid_o <= '1'; | |||
| Dout_o <= s_data; | |||
| if (DoutAccept_i = '1') then | |||
| DoutValid_o <= '0'; | |||
| s_fsm_state <= SEND_FOOTER; | |||
| end if; | |||
| when SEND_FOOTER => | |||
| DoutValid_o <= '1'; | |||
| DoutStop_o <= '1'; | |||
| Dout_o <= x"01" when s_error else x"00"; | |||
| if (DoutAccept_i = '1') then | |||
| Dout_o <= (others => '0'); | |||
| DoutValid_o <= '0'; | |||
| DoutStop_o <= '0'; | |||
| s_fsm_state <= IDLE; | |||
| end if; | |||
| when others => null; | |||
| end case; | |||
| end if; | |||
| end process; | |||
| end architecture rtl; | |||