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