- 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,
- input [7:0] s_data,
- input s_error,
- input [7:0] s_register [0:7]
- );
-
-
- // commands
- `define READ 0
- `define WRITE 1
-
- // FSM states
- `define IDLE 0
- `define GET_HEADER 1
- `define GET_DATA 2
- `define SET_DATA 3
- `define SEND_HEADER 4
- `define SEND_DATA 5
- `define SEND_FOOTER 6
-
-
- 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;
-
- // Default clocking & reset
-
- default clocking
- @(posedge Clk_i);
- endclocking
-
- default disable iff (!Reset_n_i);
-
-
- // Constraints
-
- assume property (
- DinValid_i && !DinAccept_o |=>
- $stable(DinValid_i)
- );
-
- assume property (
- DinValid_i && !DinAccept_o |=>
- $stable(Din_i)
- );
-
- assume property (
- DinValid_i && !DinAccept_o |=>
- $stable(DinStart_i)
- );
-
- assume property (
- DinValid_i && !DinAccept_o |=>
- $stable(DinStop_i)
- );
-
-
- // Asserts
-
- fsm_state_valid_a : assert property (
- s_fsm_state >= `IDLE && s_fsm_state <= `SEND_FOOTER
- );
-
- valid_when_start_a : assert property (
- DoutStart_o |->
- DoutValid_o
- );
-
- start_off_when_acked_a : assert property (
- DoutStart_o && DoutAccept_i |=>
- !DoutStart_o
- );
-
- valid_when_stop_a : assert property (
- DoutStop_o |->
- DoutValid_o
- );
-
- stop_off_when_acked_a : assert property (
- DoutStop_o && DoutAccept_i |=>
- !DoutStop_o
- );
-
- store_header_a : assert property (
- s_fsm_state == `GET_HEADER && DinValid_i && DinStart_i && DinAccept_o |=>
- s_header == $past(Din_i)
- );
-
-
- // State changes
-
- // IDLE -> GET_HEADER
- fsm_idle_to_get_header_a : assert property (
- s_fsm_state == `IDLE |=>
- s_fsm_state == `GET_HEADER
- );
-
- // GET_HEADER -> GET_DATA
- fsm_get_header_to_get_data_a : assert property (
- s_fsm_state == `GET_HEADER && DinValid_i && DinStart_i && DinStop_i && Din_i[3:0] == `READ |=>
- s_fsm_state == `GET_DATA
- );
-
- // GET_HEADER -> SET_DATA
- fsm_get_header_to_set_data_a : assert property (
- s_fsm_state == `GET_HEADER && DinValid_i && DinStart_i && !DinStop_i && Din_i[3:0] == `WRITE |=>
- s_fsm_state == `SET_DATA
- );
-
- // GET_DATA -> SEND_HEADER
- fsm_get_data_to_send_header_a : assert property (
- s_fsm_state == `GET_DATA |=>
- s_fsm_state == `SEND_HEADER
- );
-
- // SET_DATA -> IDLE
- fsm_set_data_to_idle_a : assert property (
- s_fsm_state == `SET_DATA && DinValid_i && !DinStop_i |=>
- s_fsm_state == `IDLE
- );
-
- // SET_DATA -> SEND_HEADER
- fsm_set_data_to_send_header_a : assert property (
- s_fsm_state == `SET_DATA && DinValid_i && DinStop_i |=> s_fsm_state == `SEND_HEADER
- );
-
- // SEND_HEADER -> SEND_DATA
- fsm_send_header_to_send_data_a : assert property (
- s_fsm_state == `SEND_HEADER && DoutValid_o && DoutAccept_i && s_header[3:0] == `READ |=>
- s_fsm_state == `SEND_DATA
- );
-
- // SEND_HEADER -> SEND_FOOTER
- fsm_send_header_to_send_footer_a : assert property (
- s_fsm_state == `SEND_HEADER && DoutValid_o && DoutAccept_i && s_header[3:0] == `WRITE |=>
- s_fsm_state == `SEND_FOOTER
- );
-
- // SEND_DATA -> SEND_FOOTER
- fsm_send_data_to_send_footer_a : assert property (
- s_fsm_state == `SEND_DATA && DoutValid_o && DoutAccept_i |=>
- s_fsm_state == `SEND_FOOTER
- );
-
- // SEND_FOOTER -> IDLE
- fsm_send_footer_to_idle_a : assert property (
- s_fsm_state == `SEND_FOOTER && DoutValid_o && DoutAccept_i |=>
- s_fsm_state == `IDLE
- );
-
-
- // Protocol checks
-
- header_in_valid_range_a : assert property (
- s_fsm_state > `GET_HEADER |->
- s_header[3:0] inside {`READ, `WRITE}
- );
-
- header_stable_a : assert property (
- s_fsm_state > `GET_HEADER |=>
- $stable(s_header)
- );
-
- header_dout_valid_a : assert property (
- DoutStart_o && DoutValid_o |->
- Dout_o == s_header
- );
-
- error_flag_initial_false_a : assert property (
- s_fsm_state inside {`GET_HEADER, `GET_DATA, `SET_DATA} |->
- !s_error
- );
-
- error_flag_set_invalid_addr_a : assert property (
- s_fsm_state >= `SEND_HEADER |->
- s_error == !(s_header[7:4] <= 7)
- );
-
- footer_dout_valid_a :assert property (
- DoutStop_o && DoutValid_o |->
- Dout_o == s_error
- );
-
- doutvalid_stable_until_acked_a : assert property (
- DoutValid_o && !DoutAccept_i |=>
- $stable(DoutValid_o)
- );
-
- dout_stable_until_acked_a : assert property (
- DoutValid_o && !DoutAccept_i |=>
- $stable(Dout_o)
- );
-
- doutstart_stable_until_acked_a : assert property (
- DoutValid_o && !DoutAccept_i |=>
- $stable(DoutStart_o)
- );
-
- doutstop_stable_until_acked_a : assert property (
- DoutValid_o && !DoutAccept_i |=>
- $stable(DoutStop_o)
- );
-
- onehot_doutstart_doutstop_a : assert property (
- DoutValid_o |-> $onehot0({DoutStart_o, DoutStop_o})
- );
-
- doutstart_in_valid_fsm_state_a : assert property (
- DoutStart_o |->
- s_fsm_state == `SEND_HEADER
- );
-
- doutstop_in_valid_fsm_state_a : assert property (
- DoutStop_o |->
- s_fsm_state == `SEND_FOOTER
- );
-
- doutvalid_in_valid_fsm_states_a : assert property (
- DoutValid_o |->
- s_fsm_state inside {`SEND_HEADER, `SEND_DATA, `SEND_FOOTER}
- );
-
- // Write ack frame
- write_frame_a : assert property (
- DoutValid_o && DoutStart_o && DoutAccept_i && Dout_o[3:0] == `WRITE |=>
- !DoutValid_o ##1
- DoutValid_o && DoutStop_o
- );
-
- // Read ack frame
- read_frame_a : assert property (
- DoutValid_o && DoutStart_o && DoutAccept_i && Dout_o[3:0] == `READ |=>
- !DoutValid_o ##1
- DoutValid_o && !DoutStart_o && !DoutStop_o && !DoutAccept_i [*] ##1
- DoutValid_o && !DoutStart_o && !DoutStop_o && DoutAccept_i ##1
- !DoutValid_o ##1
- DoutValid_o && DoutStop_o
- );
-
- // Register read in GET_DATA if valid adress was given
- get_data_valid_a : assert property (
- s_fsm_state > `GET_DATA && s_header[7:4] <= 7 && s_header[3:0] == `READ |->
- s_data == s_register[s_header[7:4]]
- );
-
- // Error flag set & no register read in GET_DATA if invalid adress was given
- get_data_invalid_a : assert property (
- s_fsm_state > `GET_DATA && s_header[7:4] > 7 && s_header[3:0] == `READ |=>
- s_data == 0 && s_error
- );
-
- // register stable if read request
- reg_stable_during_read_a : assert property (
- s_fsm_state > `GET_HEADER && s_header[3:0] == `READ |=>
- $stable(s_register)
- );
-
- // Read ack data correct if address is valid
- read_ack_data_valid_a : assert property (
- DoutValid_o && DoutStart_o && DoutAccept_i && Dout_o[3:0] == `READ && s_header[7:4] <= 7 |=>
- !DoutValid_o ##1
- DoutValid_o && !DoutStart_o && !DoutStop_o && Dout_o == s_data
- );
-
- // Read ack data zero if address is invalid
- read_ack_data_invalid_a : assert property (
- DoutValid_o && DoutStart_o && DoutAccept_i && Dout_o[3:0] == `READ && s_header[7:4] > 7 |=>
- !DoutValid_o ##1
- DoutValid_o && !DoutStart_o && !DoutStop_o && Dout_o == 0
- );
-
- // Register write in SET_DATA if valid adress was given
- set_data_valid_a : assert property (
- s_fsm_state == `SET_DATA && DinValid_i && DinAccept_o && DinStop_i && s_header[7:4] <= 7 |=>
- s_register[s_header[7:4]] == $past(Din_i)
- );
-
- // Error flag set & no register write in SET_DATA if invalid adress was given
- set_data_invalid_a : assert property (
- s_fsm_state == `SET_DATA && DinValid_i && DinAccept_o && DinStop_i && s_header[7:4] > 7 |=>
- $stable(s_register) && s_error
- );
-
- // No register write in SET_DATA if stop don't active
- set_data_discard_a : assert property (
- s_fsm_state == `SET_DATA && DinValid_i && DinAccept_o && !DinStop_i |=>
- $stable(s_register)
- );
-
- fsm_read_req_when_get_data_a : assert property (
- s_fsm_state == `GET_DATA |-> s_header[3:0] == `READ
- );
-
- fsm_write_req_when_set_data_a : assert property (
- s_fsm_state == `SET_DATA |-> s_header[3:0] == `WRITE
- );
-
-
- endmodule
-
-
- bind vai_reg properties properties (.*);
|