blob: c08376a0df9b5b8e54ab0e43352ddb3322cff3c5 [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 padctrl_assert_fpv (
input clk_i,
input rst_ni,
// Bus Interface (device)
input tlul_pkg::tl_h2d_t tl_i,
input tlul_pkg::tl_d2h_t tl_o,
// pad attributes to chip level instance
input logic[padctrl_reg_pkg::NMioPads-1:0]
[padctrl_reg_pkg::AttrDw-1:0] mio_attr_o,
input logic[padctrl_reg_pkg::NDioPads-1:0]
[padctrl_reg_pkg::AttrDw-1:0] dio_attr_o
);
import prim_pkg::*;
// symbolic vars for FPV
int unsigned mio_sel;
int unsigned dio_sel;
/////////////////////////
// Check muxed IO pads //
/////////////////////////
logic [padctrl_reg_pkg::NMioPads-1:0][padctrl_reg_pkg::AttrDw-1:0] mio_warl_masks;
for (genvar k = 0; k < padctrl_reg_pkg::NMioPads; k++) begin : gen_mio_attr
prim_generic_pad_wrapper #(
.AttrDw ( padctrl_reg_pkg::AttrDw ),
.WarlOnly ( 1'b1 )
) i_prim_generic_pad_wrapper (
.inout_io ( ),
.in_o ( ),
.ie_i ( 1'b0 ),
.out_i ( 1'b0 ),
.oe_i ( 1'b0 ),
.attr_i ( '0 ),
.warl_o ( mio_warl_masks[k] )
);
end
`ASSUME(NMioRange_M, mio_sel < padctrl_reg_pkg::NMioPads, clk_i, !rst_ni)
`ASSUME(NMioStable_M, ##1 $stable(mio_sel), clk_i, !rst_ni)
`ASSERT(MioWarl_A, padctrl.reg2hw.mio_pads[mio_sel].qe |=>
(~mio_warl_masks[mio_sel] & mio_attr_o[mio_sel]) == '0)
`ASSERT(MioAttr_A, padctrl.reg2hw.mio_pads[mio_sel].qe |=>
mio_attr_o[mio_sel] ==
$past(padctrl.reg2hw.mio_pads[mio_sel].q & mio_warl_masks[mio_sel]))
`ASSERT(MioBackwardCheck_A, ##2 !$stable(mio_attr_o[mio_sel]) |->
!$stable(padctrl.reg2hw.mio_pads[mio_sel] & mio_warl_masks[mio_sel]) ||
$rose($past(padctrl.reg2hw.mio_pads[mio_sel].qe)))
/////////////////////////////
// Check dedicated IO pads //
/////////////////////////////
logic [padctrl_reg_pkg::NDioPads-1:0][padctrl_reg_pkg::AttrDw-1:0] dio_warl_masks;
for (genvar k = 0; k < padctrl_reg_pkg::NDioPads; k++) begin : gen_dio_attr
prim_generic_pad_wrapper #(
.AttrDw ( padctrl_reg_pkg::AttrDw ),
.WarlOnly ( 1'b1 )
) i_prim_generic_pad_wrapper (
.inout_io ( ),
.in_o ( ),
.ie_i ( 1'b0 ),
.out_i ( 1'b0 ),
.oe_i ( 1'b0 ),
.attr_i ( '0 ),
.warl_o ( dio_warl_masks[k] )
);
end
`ASSUME(NDioRange_M, dio_sel < padctrl_reg_pkg::NDioPads, clk_i, !rst_ni)
`ASSUME(NDioStable_M, ##1 $stable(dio_sel), clk_i, !rst_ni)
`ASSERT(DioWarl_A, padctrl.reg2hw.mio_pads[mio_sel].qe |=>
(~dio_warl_masks[dio_sel] & dio_attr_o[dio_sel]) == '0)
`ASSERT(DioAttr_A, padctrl.reg2hw.dio_pads[dio_sel].qe |=>
dio_attr_o[dio_sel] ==
$past(padctrl.reg2hw.dio_pads[dio_sel].q & dio_warl_masks[dio_sel]))
`ASSERT(DioBackwardCheck_A, ##2 !$stable(dio_attr_o[dio_sel]) |->
!$stable(padctrl.reg2hw.dio_pads[dio_sel] & dio_warl_masks[dio_sel]) ||
$rose($past(padctrl.reg2hw.dio_pads[dio_sel].qe)))
endmodule : padctrl_assert_fpv