blob: 6ca2b29c9cfdf7ea0f1db6fc09af9f911fd64ae1 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// This is the pinmux portion that has to be instantiated on the chip level.
// The module instantiates the technology dependent pads, and connects them
// to the MIOs/DIOs and pad attributes coming from the pinmux block.
//
`include "prim_assert.sv"
module padring import pinmux_reg_pkg::*; #(
// This allows to selectively connect Pad instances.
// unconnected inputs are tied to 0, unconnected outputs are high-z.
parameter bit ConnectClk = 1,
parameter bit ConnectRst = 1,
parameter bit [1:0] ConnectCc = '1,
parameter bit [NMioPads-1:0] ConnectMioIn = '1,
parameter bit [NMioPads-1:0] ConnectMioOut = '1,
parameter bit [NDioPads-1:0] ConnectDioIn = '1,
parameter bit [NDioPads-1:0] ConnectDioOut = '1,
// 0: bidir, 1: input, 2: tolerant, 3: open drain
parameter bit [NMioPads-1:0][1:0] MioPadVariant = '0,
parameter bit [NDioPads-1:0][1:0] DioPadVariant = '0
) (
// pad input
input wire clk_pad_i,
input wire rst_pad_ni,
// to clocking/reset infrastructure
output logic clk_o,
output logic rst_no,
// pads for dcd.
input wire cc1_i,
input wire cc2_i,
// pads
inout wire [NMioPads-1:0] mio_pad_io,
inout wire [NDioPads-1:0] dio_pad_io,
// muxed IO signals coming from pinmux
output logic [NMioPads-1:0] mio_in_o,
input [NMioPads-1:0] mio_out_i,
input [NMioPads-1:0] mio_oe_i,
// dedicated IO signals coming from peripherals
output logic [NDioPads-1:0] dio_in_o,
input [NDioPads-1:0] dio_out_i,
input [NDioPads-1:0] dio_oe_i,
// pad attributes from top level instance
input [NMioPads-1:0][AttrDw-1:0] mio_attr_i,
input [NDioPads-1:0][AttrDw-1:0] dio_attr_i
);
/////////////////////////
// Clock / Reset Infra //
/////////////////////////
// use this intermediate assignment to make both lint and fpv happy.
// the clock/reset wires should be input-only, otherwise fpv
// has trouble defining/tracing the clock signal. on the other hand, a direct
// connection of input wire to an inout pad causes lint problems
// (even though oe is hardwired to 0).
wire clk, rst_n;
assign clk = clk_pad_i;
assign rst_n = rst_pad_ni;
if (ConnectClk) begin : gen_clk_pad
prim_pad_wrapper #(
.AttrDw ( AttrDw ),
.Variant ( 1 ) // input-only
) u_clk_pad (
.inout_io ( clk ),
.in_o ( clk_o ),
.ie_i ( 1'b1 ),
.out_i ( 1'b0 ),
.oe_i ( 1'b0 ),
.attr_i ( '0 ),
.warl_o ( )
);
end else begin : gen_no_clk_pad
logic unused_clk;
assign unused_clk = clk;
assign clk_o = 1'b0;
end
if (ConnectRst) begin : gen_rst_pad
prim_pad_wrapper #(
.AttrDw ( AttrDw ),
.Variant ( 1 ) // input-only
) u_rst_pad (
.inout_io ( rst_n ),
.in_o ( rst_no ),
.ie_i ( 1'b1 ),
.out_i ( 1'b0 ),
.oe_i ( 1'b0 ),
.attr_i ( '0 ),
.warl_o ( )
);
end else begin : gen_no_rst_pad
logic unused_rst;
assign unused_rst = rst_n;
assign rst_no = 1'b0;
end
//////////////////
// Pads for DCD //
//////////////////
// Note that analog connections to these pads are made in physical design.
// None of the digital signals are used here.
wire cc1, cc2;
assign cc1 = cc1_i;
assign cc2 = cc2_i;
if (ConnectCc[0]) begin : gen_cc1_pad
prim_pad_wrapper #(
.AttrDw ( AttrDw ),
.Variant ( 1 ) // input-only
) u_cc1_pad (
.inout_io ( cc1 ),
.in_o ( ),
.ie_i ( 1'b0 ), // input buffer disabled
.out_i ( 1'b0 ),
.oe_i ( 1'b0 ),
.attr_i ( '0 ),
.warl_o ( )
);
end else begin : gen_no_cc1_pad
logic unused_cc1;
assign unused_cc1 = cc1;
end
if (ConnectCc[1]) begin : gen_cc2_pad
prim_pad_wrapper #(
.AttrDw ( AttrDw ),
.Variant ( 1 ) // input-only
) u_cc2_pad (
.inout_io ( cc2 ),
.in_o ( ),
.ie_i ( 1'b0 ), // input buffer disabled
.out_i ( 1'b0 ),
.oe_i ( 1'b0 ),
.attr_i ( '0 ),
.warl_o ( )
);
end else begin : gen_no_cc2_pad
logic unused_cc2;
assign unused_cc2 = cc2;
end
//////////////
// MIO Pads //
//////////////
for (genvar k = 0; k < NMioPads; k++) begin : gen_mio_pads
if (ConnectMioIn[k] && ConnectMioOut[k]) begin : gen_mio_inout
prim_pad_wrapper #(
.AttrDw ( AttrDw ),
.Variant ( MioPadVariant[k] )
) u_mio_pad (
.inout_io ( mio_pad_io[k] ),
.in_o ( mio_in_o[k] ),
.ie_i ( 1'b1 ),
.out_i ( mio_out_i[k] ),
.oe_i ( mio_oe_i[k] ),
.attr_i ( mio_attr_i[k] ),
.warl_o ( )
);
end else if (ConnectMioOut[k]) begin : gen_mio_output
prim_pad_wrapper #(
.AttrDw ( AttrDw ),
.Variant ( MioPadVariant[k] )
) u_mio_pad (
.inout_io ( mio_pad_io[k] ),
.in_o ( ),
.ie_i ( 1'b0 ),
.out_i ( mio_out_i[k] ),
.oe_i ( mio_oe_i[k] ),
.attr_i ( mio_attr_i[k] ),
.warl_o ( )
);
assign mio_in_o[k] = 1'b0;
end else if (ConnectMioIn[k]) begin : gen_mio_input
prim_pad_wrapper #(
.AttrDw ( AttrDw ),
.Variant ( MioPadVariant[k] )
) u_mio_pad (
.inout_io ( mio_pad_io[k] ),
.in_o ( mio_in_o[k] ),
.ie_i ( 1'b1 ),
.out_i ( 1'b0 ),
.oe_i ( 1'b0 ),
.attr_i ( mio_attr_i[k] ),
.warl_o ( )
);
logic unused_out, unused_oe;
assign unused_out = mio_out_i[k];
assign unused_oe = mio_oe_i[k];
end else begin : gen_mio_tie_off
logic unused_out, unused_oe, unused_pad;
logic [AttrDw-1:0] unused_attr;
assign mio_pad_io[k] = 1'b0;
assign unused_pad = mio_pad_io[k];
assign unused_out = mio_out_i[k];
assign unused_oe = mio_oe_i[k];
assign unused_attr = mio_attr_i[k];
assign mio_in_o[k] = 1'b0;
end
end
//////////////
// DIO Pads //
//////////////
for (genvar k = 0; k < NDioPads; k++) begin : gen_dio_pads
if (ConnectDioIn[k] && ConnectDioOut[k]) begin : gen_dio_inout
prim_pad_wrapper #(
.AttrDw ( AttrDw ),
.Variant ( DioPadVariant[k] )
) u_dio_pad (
.inout_io ( dio_pad_io[k] ),
.in_o ( dio_in_o[k] ),
.ie_i ( 1'b1 ),
.out_i ( dio_out_i[k] ),
.oe_i ( dio_oe_i[k] ),
.attr_i ( dio_attr_i[k] ),
.warl_o ( )
);
end else if (ConnectDioOut[k]) begin : gen_dio_output
prim_pad_wrapper #(
.AttrDw ( AttrDw ),
.Variant ( DioPadVariant[k] )
) u_dio_pad (
.inout_io ( dio_pad_io[k] ),
.in_o ( ),
.ie_i ( 1'b0 ),
.out_i ( dio_out_i[k] ),
.oe_i ( dio_oe_i[k] ),
.attr_i ( dio_attr_i[k] ),
.warl_o ( )
);
assign dio_in_o[k] = 1'b0;
end else if (ConnectDioIn[k]) begin : gen_dio_input
prim_pad_wrapper #(
.AttrDw ( AttrDw ),
.Variant ( DioPadVariant[k] )
) u_dio_pad (
.inout_io ( dio_pad_io[k] ),
.in_o ( dio_in_o[k] ),
.ie_i ( 1'b1 ),
.out_i ( 1'b0 ),
.oe_i ( 1'b0 ),
.attr_i ( dio_attr_i[k] ),
.warl_o ( )
);
logic unused_out, unused_oe;
assign unused_out = dio_out_i[k];
assign unused_oe = dio_oe_i[k];
end else begin : gen_dio_tie_off
logic unused_out, unused_oe, unused_pad;
logic [AttrDw-1:0] unused_attr;
assign dio_pad_io[k] = 1'b0;
assign unused_pad = dio_pad_io[k];
assign unused_out = dio_out_i[k];
assign unused_oe = dio_oe_i[k];
assign unused_attr = dio_attr_i[k];
assign dio_in_o[k] = 1'b0;
end
end
endmodule : padring