| @ -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; | |||||