blob: 7c8349d90a3fffdb5c7012d9bcd13e5f1c2a453b [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------//
// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND:
//
// hw/ip/prim/util/generate_prim_mubi.py
//
// Double-synchronizer flop for multibit signals with additional output buffers.
`include "prim_assert.sv"
module prim_mubi${n_bits}_sync
import prim_mubi_pkg::*;
#(
// Number of separately buffered output signals.
// The buffer cells have a don't touch constraint
// on them such that synthesis tools won't collapse
// all copies into one signal.
parameter int NumCopies = 1,
// This instantiates the synchronizer flops if set to 1.
// In special cases where the receiver is in the same clock domain as the sender,
// this can be set to 0. However, it is recommended to leave this at 1.
parameter bit AsyncOn = 1,
// Reset value for the sync flops
parameter mubi${n_bits}_t ResetValue = MuBi${n_bits}False
) (
input clk_i,
input rst_ni,
input mubi${n_bits}_t mubi_i,
output mubi${n_bits}_t [NumCopies-1:0] mubi_o
);
`ASSERT_INIT(NumCopiesMustBeGreaterZero_A, NumCopies > 0)
logic [MuBi${n_bits}Width-1:0] mubi;
if (AsyncOn) begin : gen_flops
prim_flop_2sync #(
.Width(MuBi${n_bits}Width),
.ResetValue(MuBi${n_bits}Width'(ResetValue))
) u_prim_flop_2sync (
.clk_i,
.rst_ni,
.d_i(mubi_i),
.q_o(mubi)
);
end else begin : gen_no_flops
logic unused_clk;
logic unused_rst;
assign unused_clk = clk_i;
assign unused_rst = rst_ni;
assign mubi = mubi_i;
end
for (genvar j = 0; j < NumCopies; j++) begin : gen_buffs
logic [MuBi${n_bits}Width-1:0] mubi_out;
for (genvar k = 0; k < MuBi${n_bits}Width; k++) begin : gen_bits
prim_buf u_prim_buf (
.in_i(mubi[k]),
.out_o(mubi_out[k])
);
end
assign mubi_o[j] = mubi${n_bits}_t'(mubi_out);
end
////////////////
// Assertions //
////////////////
// The outputs should be known at all times.
`ASSERT_KNOWN(OutputsKnown_A, mubi_o)
// If the multibit signal is in a transient state, we expect it
// to be stable again within one clock cycle.
// DV will exclude these three assertions by name, thus added a module name prefix to make it
// harder to accidentally replicate in other modules.
`ASSERT(PrimMubi${n_bits}SyncCheckTransients_A,
!(mubi_i inside {MuBi${n_bits}True, MuBi${n_bits}False})
|=>
(mubi_i inside {MuBi${n_bits}True, MuBi${n_bits}False}))
// If a signal departs from passive state, we expect it to move to the active state
// with only one transient cycle in between.
`ASSERT(PrimMubi${n_bits}SyncCheckTransients0_A,
$past(mubi_i == MuBi${n_bits}False) &&
!(mubi_i inside {MuBi${n_bits}True, MuBi${n_bits}False})
|=>
(mubi_i == MuBi${n_bits}True))
`ASSERT(PrimMubi${n_bits}SyncCheckTransients1_A,
$past(mubi_i == MuBi${n_bits}True) &&
!(mubi_i inside {MuBi${n_bits}True, MuBi${n_bits}False})
|=>
(mubi_i == MuBi${n_bits}False))
endmodule : prim_mubi${n_bits}_sync