blob: 571e394cd098a0de6e3c4d7027349919f6f3c335 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Bidirectional IO buffer for Xilinx FPGAs. Implements inversion and
// virtual open drain feature.
`include "prim_assert.sv"
module prim_xilinx_pad_wrapper
import prim_pad_wrapper_pkg::*;
#(
// These parameters are ignored in this Xilinx variant.
parameter pad_type_e PadType = BidirStd,
parameter scan_role_e ScanRole = NoScan
) (
// This is only used for scanmode (not used in this Xilinx variant)
input clk_scan_i,
input scanmode_i,
// Power sequencing signals (not used in this Xilinx variant)
input pad_pok_t pok_i,
// Main Pad signals
inout wire inout_io, // bidirectional pad
output logic in_o, // input data
output logic in_raw_o, // uninverted output data
input ie_i, // input enable
input out_i, // output data
input oe_i, // output enable
input pad_attr_t attr_i // additional pad attributes
);
// analog pads cannot have a scan role.
`ASSERT_INIT(AnalogNoScan_A, PadType != AnalogIn0 || ScanRole == NoScan)
// not all signals are used here.
logic unused_sigs;
assign unused_sigs = ^{attr_i.slew_rate,
attr_i.drive_strength,
attr_i.od_en,
attr_i.schmitt_en,
attr_i.keep_en,
attr_i.pull_en,
attr_i.pull_select,
scanmode_i,
pok_i};
if (PadType == InputStd) begin : gen_input_only
logic unused_sigs;
assign unused_sigs = ^{out_i,
oe_i,
attr_i.virt_od_en};
// input inversion
logic in;
assign in_raw_o = (ie_i) ? in : 1'bz;
assign in_o = attr_i.invert ^ in_raw_o;
IBUF u_ibuf (
.I ( inout_io ),
.O ( in )
);
end else if (PadType == BidirTol ||
PadType == DualBidirTol ||
PadType == BidirOd ||
PadType == BidirStd) begin : gen_bidir
// input inversion
logic in;
assign in_raw_o = (ie_i) ? in : 1'bz;
assign in_o = attr_i.invert ^ in_raw_o;
// virtual open drain emulation
logic oe_n, out;
assign out = out_i ^ attr_i.invert;
// oe_n = 0: enable driver
// oe_n = 1: disable driver
assign oe_n = ~oe_i | (out & attr_i.virt_od_en);
IOBUF u_iobuf (
.T ( oe_n ),
.I ( out ),
.O ( in ),
.IO ( inout_io )
);
end else if (PadType == AnalogIn0 || PadType == AnalogIn1) begin : gen_analog
logic unused_sigs;
assign unused_sigs = ^{out_i,
oe_i,
attr_i.invert,
attr_i.virt_od_en};
// this is currently modeled as a logic feed through.
IBUF u_ibuf (
.I ( inout_io ),
.O ( in_raw_o )
);
assign in_raw_o = inout_io;
end else begin : gen_invalid_config
// this should throw link warnings in elaboration
assert_static_in_generate_config_not_available
assert_static_in_generate_config_not_available();
end
endmodule : prim_xilinx_pad_wrapper