blob: d266e2414e45dc09312a99913c92bf2a699ee54f [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Assertions for padring. Intended to use with a formal tool.
// Note that only the mandatory pad attributes are tested here.
`include "prim_assert.sv"
module padring_assert_fpv (
input clk_pad_i,
input rst_pad_ni,
input clk_o,
input rst_no,
input [padctrl_reg_pkg::NMioPads-1:0] mio_pad_io,
input [padctrl_reg_pkg::NDioPads-1:0] dio_pad_io,
input [padctrl_reg_pkg::NMioPads-1:0] mio_out_i,
input [padctrl_reg_pkg::NMioPads-1:0] mio_oe_i,
input [padctrl_reg_pkg::NMioPads-1:0] mio_in_o,
input [padctrl_reg_pkg::NDioPads-1:0] dio_out_i,
input [padctrl_reg_pkg::NDioPads-1:0] dio_oe_i,
input [padctrl_reg_pkg::NDioPads-1:0] dio_in_o,
input [padctrl_reg_pkg::NMioPads-1:0]
[padctrl_reg_pkg::AttrDw-1:0] mio_attr_i,
input [padctrl_reg_pkg::NDioPads-1:0]
[padctrl_reg_pkg::AttrDw-1:0] dio_attr_i
);
// symbolic vars for FPV
int unsigned mio_sel;
int unsigned dio_sel;
///////////////////////////////////////////////////////
// Check main connectivity of infrastructure signals //
///////////////////////////////////////////////////////
`ASSERT(ClkConn_A, clk_pad_i === clk_o, clk_pad_i, !rst_pad_ni)
`ASSERT(RstConn_A, rst_pad_ni === rst_no, clk_pad_i, !rst_pad_ni)
/////////////////////////
// Check muxed IO pads //
/////////////////////////
`ASSUME(NMioRange_M, mio_sel < padctrl_reg_pkg::NMioPads, clk_pad_i, !rst_pad_ni)
`ASSUME(NMioStable_M, ##1 $stable(mio_sel), clk_pad_i, !rst_pad_ni)
// attribute 0 is the input/output inversion bit
logic mio_output_value;
assign mio_output_value = mio_out_i[mio_sel] ^ mio_attr_i[mio_sel][0];
`ASSERT(MioIn_A, mio_in_o[mio_sel] == mio_pad_io[mio_sel] ^ mio_attr_i[mio_sel][0],
clk_pad_i, !rst_pad_ni)
`ASSERT(MioInBackwardCheck_A, ##1 !$stable(mio_in_o[mio_sel]) |->
!$stable(mio_pad_io[mio_sel]) || !$stable(mio_attr_i[mio_sel][0]),
clk_pad_i, !rst_pad_ni)
`ASSERT(MioOutNormal_A, mio_oe_i[mio_sel] && !mio_attr_i[mio_sel][1] |->
mio_output_value == mio_pad_io[mio_sel], clk_pad_i, !rst_pad_ni)
`ASSERT(MioOutOd0_A, mio_oe_i[mio_sel] && mio_attr_i[mio_sel][1] && !mio_output_value |->
mio_pad_io[mio_sel] == 1'b0, clk_pad_i, !rst_pad_ni)
// TODO: find a better way to test high-Z?
`ASSERT(MioOutOd1_A, mio_oe_i[mio_sel] && mio_attr_i[mio_sel][1] && mio_output_value |->
mio_pad_io[mio_sel] === 1'b0 ||
mio_pad_io[mio_sel] === 1'b1 ||
mio_pad_io[mio_sel] === 1'bz ||
mio_pad_io[mio_sel] === 1'bx, clk_pad_i, !rst_pad_ni)
// TODO: find a better way to test high-Z?
`ASSERT(MioOe_A, !mio_oe_i[mio_sel] |->
mio_pad_io[mio_sel] === 1'b0 ||
mio_pad_io[mio_sel] === 1'b1 ||
mio_pad_io[mio_sel] === 1'bz ||
mio_pad_io[mio_sel] === 1'bx, clk_pad_i, !rst_pad_ni)
/////////////////////////////
// Check dedicated IO pads //
/////////////////////////////
`ASSUME(NDioRange_M, dio_sel < padctrl_reg_pkg::NDioPads, clk_pad_i, !rst_pad_ni)
`ASSUME(NDioStable_M, ##1 $stable(dio_sel), clk_pad_i, !rst_pad_ni)
// attribute 0 is the input/output inversion bit
logic dio_output_value;
assign dio_output_value = dio_out_i[dio_sel] ^ dio_attr_i[dio_sel][0];
`ASSERT(DioIn_A, dio_in_o[dio_sel] == dio_pad_io[dio_sel] ^ dio_attr_i[dio_sel][0],
clk_pad_i, !rst_pad_ni)
`ASSERT(DioInBackwardCheck_A, ##1 !$stable(dio_in_o[dio_sel]) |->
!$stable(dio_pad_io[dio_sel]) || !$stable(dio_attr_i[dio_sel][0]),
clk_pad_i, !rst_pad_ni)
`ASSERT(DioOutNormal_A, dio_oe_i[dio_sel] && !dio_attr_i[dio_sel][1] |->
dio_output_value == dio_pad_io[dio_sel], clk_pad_i, !rst_pad_ni)
`ASSERT(DioOutOd0_A, dio_oe_i[dio_sel] && dio_attr_i[dio_sel][1] && !dio_output_value |->
dio_pad_io[dio_sel] == 1'b0, clk_pad_i, !rst_pad_ni)
// TODO: find a better way to test high-Z?
`ASSERT(DioOutOd1_A, dio_oe_i[dio_sel] && dio_attr_i[dio_sel][1] && dio_output_value |->
dio_pad_io[dio_sel] === 1'b0 ||
dio_pad_io[dio_sel] === 1'b1 ||
dio_pad_io[dio_sel] === 1'bz ||
dio_pad_io[dio_sel] === 1'bx, clk_pad_i, !rst_pad_ni)
// TODO: find a better way to test high-Z?
`ASSERT(DioOe_A, !dio_oe_i[dio_sel] |->
dio_pad_io[dio_sel] === 1'b0 ||
dio_pad_io[dio_sel] === 1'b1 ||
dio_pad_io[dio_sel] === 1'bz ||
dio_pad_io[dio_sel] === 1'bx, clk_pad_i, !rst_pad_ni)
endmodule : padring_assert_fpv