blob: 8c81a7b5468e4769ec96ede37b785ae84dec71c6 [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:
//
// util/design/gen-mubi.py
//
// Multibit sender module. This module is instantiates a hand-picked flop cell for each bit in the
// multibit signal such that tools do not optimize the multibit encoding.
`include "prim_assert.sv"
module prim_mubi${n_bits}_sender
import prim_mubi_pkg::*;
#(
// This flops the output if set to 1.
// In special cases where the sender is in the same clock domain as the receiver,
// this can be set to 0. However, it is recommended to leave this at 1.
parameter bit AsyncOn = 1,
// Enable anchor buffer
parameter bit EnSecBuf = 0,
// Reset value for the sender 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 mubi_o
);
logic [MuBi${n_bits}Width-1:0] mubi, mubi_int, mubi_out;
assign mubi = MuBi${n_bits}Width'(mubi_i);
// first generation block decides whether a flop should be present
if (AsyncOn) begin : gen_flops
prim_flop #(
.Width(MuBi${n_bits}Width),
.ResetValue(MuBi${n_bits}Width'(ResetValue))
) u_prim_flop (
.clk_i,
.rst_ni,
.d_i ( mubi ),
.q_o ( mubi_int )
);
end else begin : gen_no_flops
assign mubi_int = mubi;
// This unused companion logic helps remove lint errors
// for modules where clock and reset are used for assertions only
// This logic will be removed for sythesis since it is unloaded.
mubi${n_bits}_t unused_logic;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
unused_logic <= MuBi${n_bits}False;
end else begin
unused_logic <= mubi_i;
end
end
end
// second generation block determines output buffer type
// 1. If EnSecBuf -> always leads to a sec buffer regardless of first block
// 2. If not EnSecBuf and not AsyncOn -> use normal buffer
// 3. If not EnSecBuf and AsyncOn -> feed through
if (EnSecBuf) begin : gen_sec_buf
prim_sec_anchor_buf #(
.Width(${n_bits})
) u_prim_sec_buf (
.in_i(mubi_int),
.out_o(mubi_out)
);
end else if (!AsyncOn) begin : gen_prim_buf
prim_buf #(
.Width(${n_bits})
) u_prim_buf (
.in_i(mubi_int),
.out_o(mubi_out)
);
end else begin : gen_feedthru
assign mubi_out = mubi_int;
end
assign mubi_o = mubi${n_bits}_t'(mubi_out);
////////////////
// Assertions //
////////////////
// The outputs should be known at all times.
`ASSERT_KNOWN(OutputsKnown_A, mubi_o)
endmodule : prim_mubi${n_bits}_sender