blob: ef69dbf2f37e4aaed3a0729ed68671e7ce051af4 [file] [log] [blame]
/*
* Copyright 2020 The SkyWater PDK Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
module sky130_fd_io__top_refgen_new (VINREF, VOUTREF, REFLEAK_BIAS,
AMUXBUS_A, AMUXBUS_B, DFT_REFGEN, HLD_H_N, IBUF_SEL, ENABLE_H, ENABLE_VDDA_H, VOH_SEL, VOHREF,
VREF_SEL, VREG_EN, VTRIP_SEL, VOUTREF_DFT, VINREF_DFT);
output VINREF;
output VOUTREF;
inout REFLEAK_BIAS;
supply1 vccd;
supply1 vcchib;
supply1 vdda;
supply1 vddio;
supply1 vddio_q;
supply0 vssd;
supply0 vssio;
supply0 vssio_q;
supply1 vswitch;
supply0 vssa;
inout AMUXBUS_A;
inout AMUXBUS_B;
input DFT_REFGEN;
input HLD_H_N;
input IBUF_SEL;
input ENABLE_H;
input ENABLE_VDDA_H;
input [2:0] VOH_SEL;
input VOHREF;
input [1:0] VREF_SEL;
input VREG_EN;
input VTRIP_SEL;
inout VOUTREF_DFT;
inout VINREF_DFT;
reg ibuf_sel_final, vtrip_sel_final, vreg_en_final, dft_refgen_final, vref_sel_int_final;
reg [2:0] voh_sel_final;
reg [1:0] vref_sel_final;
reg vohref_int;
wire pwr_good_active_mode_1 = 1;
wire pwr_good_hold_mode_1 = 1;
wire pwr_good_hold_mode_2 = 1;
wire pwr_good_active_mode_2 = 1;
wire pwr_good_hold_mode_3 = 1;
wire pwr_good_active_mode_3 = 1;
`ifdef SKY130_FD_IO_TOP_REFGEN_NEW_DISABLE_DELAY
parameter STARTUP_TIME_VOUTREF = 0;
parameter STARTUP_TIME_VINREF = 0;
`else
parameter STARTUP_TIME_VOUTREF = 50000;
parameter STARTUP_TIME_VINREF = 50000;
`endif
integer startup_time_vinref,startup_time_voutref;
initial begin
startup_time_vinref = vref_sel_int_final===1 && vtrip_sel_final===0 ? STARTUP_TIME_VINREF : 0;
startup_time_voutref = STARTUP_TIME_VOUTREF;
end
wire notifier_enable_h, notifier_vtrip_sel, notifier_ibuf_sel, notifier_vref_sel,
notifier_voh_sel, notifier_vreg_en, notifier_dft_refgen, notifier_vref_sel_int;
always @(*)
begin : LATCH_ibuf_sel
if (^ENABLE_H===1'bx || !pwr_good_hold_mode_1 || (ENABLE_H===1 && ^HLD_H_N===1'bx))
ibuf_sel_final <= 1'bx;
else if (ENABLE_H===0)
ibuf_sel_final <= 1'b0;
else if (HLD_H_N===1)
ibuf_sel_final <= (^IBUF_SEL === 1'bx || !pwr_good_active_mode_1) ? 1'bx : IBUF_SEL;
end
always @(notifier_enable_h or notifier_ibuf_sel)
begin
disable LATCH_ibuf_sel; ibuf_sel_final <= 1'bx;
end
always @(*)
begin : LATCH_vtrip_sel
if (^ENABLE_H===1'bx || !pwr_good_hold_mode_1 || (ENABLE_H===1 && ^HLD_H_N===1'bx))
vtrip_sel_final <= 1'bx;
else if (ENABLE_H===0)
vtrip_sel_final <= 1'b0;
else if (HLD_H_N===1)
vtrip_sel_final <= (^VTRIP_SEL === 1'bx || !pwr_good_active_mode_1) ? 1'bx : VTRIP_SEL;
end
always @(notifier_enable_h or notifier_vtrip_sel)
begin
disable LATCH_vtrip_sel; vtrip_sel_final <= 1'bx;
end
always @(*)
begin : LATCH_vreg_en
if (^ENABLE_H===1'bx || !pwr_good_hold_mode_1 || (ENABLE_H===1 && ^HLD_H_N===1'bx))
vreg_en_final <= 1'bx;
else if (ENABLE_H===0)
vreg_en_final <= 1'b0;
else if (HLD_H_N===1)
vreg_en_final <= (^VREG_EN === 1'bx || !pwr_good_active_mode_1) ? 1'bx : VREG_EN;
end
always @(notifier_enable_h or notifier_vreg_en)
begin
disable LATCH_vreg_en; vreg_en_final <= 1'bx;
end
always @(*)
begin : LATCH_vref_sel_int
if (^ENABLE_H===1'bx || !pwr_good_hold_mode_1 || (ENABLE_H===1 && ^HLD_H_N===1'bx))
vref_sel_int_final <= 1'bx;
else if (ENABLE_H===0)
vref_sel_int_final <= 1'b0;
else if (HLD_H_N===1)
vref_sel_int_final <= (^VREF_SEL[1:0] === 1'bx || !pwr_good_active_mode_1) ? 1'bx : (VREF_SEL[1] || VREF_SEL[0]);
end
always @(notifier_enable_h or notifier_vref_sel_int)
begin
disable LATCH_vref_sel; vref_sel_int_final <= 1'bx;
end
always @(*)
begin : LATCH_vref_sel
if (^ENABLE_VDDA_H===1'bx || ^ENABLE_H===1'bx ||!pwr_good_hold_mode_2 || (ENABLE_VDDA_H===1 && ENABLE_H===1 && ^HLD_H_N===1'bx))
vref_sel_final = 2'bxx;
else if (ENABLE_VDDA_H===0 || ENABLE_H===0)
vref_sel_final = 2'b00;
else if (HLD_H_N===1)
vref_sel_final = (^VREF_SEL[1:0]=== 1'bx || !pwr_good_active_mode_2) ? 2'bxx : VREF_SEL;
end
always @(notifier_enable_h or notifier_vref_sel)
begin
disable LATCH_vref_sel; vref_sel_final <= 2'bxx;
end
always @(*)
begin : LATCH_dft_refgen
if (^ENABLE_VDDA_H===1'bx || ^ENABLE_H===1'bx ||!pwr_good_hold_mode_2 || (ENABLE_VDDA_H===1 && ENABLE_H===1 &&^HLD_H_N===1'bx))
dft_refgen_final = 2'bxx;
else if (ENABLE_VDDA_H===0 || ENABLE_H===0)
dft_refgen_final = 2'b00;
else if (HLD_H_N===1)
dft_refgen_final = (^DFT_REFGEN=== 1'bx || !pwr_good_active_mode_2) ? 2'bxx : DFT_REFGEN;
end
always @(notifier_enable_h or notifier_dft_refgen)
begin
disable LATCH_dft_refgen; dft_refgen_final <= 2'bxx;
end
always @(*)
begin : LATCH_voh_sel
if (^ENABLE_VDDA_H===1'bx ||^ENABLE_H===1'bx || !pwr_good_hold_mode_3 || (ENABLE_VDDA_H===1 && ENABLE_H===1 && ^HLD_H_N===1'bx))
voh_sel_final = 3'bxxx;
else if (ENABLE_VDDA_H===0 || ENABLE_H===0)
voh_sel_final = 3'b000;
else if (HLD_H_N===1)
voh_sel_final = (^VOH_SEL[2:0]=== 1'bx || !pwr_good_active_mode_3) ? 3'bxxx : VOH_SEL;
end
always @(notifier_enable_h or notifier_voh_sel)
begin
disable LATCH_voh_sel; voh_sel_final <= 2'bxx;
end
always @(*)
begin
case (vref_sel_final[1:0])
2'b00, 2'b01 : vohref_int = VOHREF!==1'b1 ? 1'bx : VOHREF;
2'b10 : vohref_int = ^AMUXBUS_A!==1'b1 ? 1'bx : AMUXBUS_A;
2'b11 : vohref_int = ^AMUXBUS_B!==1'b1 ? 1'bx : AMUXBUS_B;
default : vohref_int = 1'bx;
endcase
end
wire vohref_final = ENABLE_VDDA_H===1'b1 ? vohref_int : 1'bx;
assign #(startup_time_voutref,0) VOUTREF = (REFLEAK_BIAS===1'bx) ? 1'bx : (REFLEAK_BIAS===1 ? vohref_final:1'bz);
assign VOUTREF_DFT = dft_refgen_final===1 ? VOUTREF : (dft_refgen_final===0 ? 1'bz : 1'bx);
assign REFLEAK_BIAS = vcchib!==1 ? 1'bx : (vreg_en_final || (ibuf_sel_final && vref_sel_int_final));
reg vinref_tmp;
always @(*)
begin
if (ibuf_sel_final===1'bx
|| (ibuf_sel_final===1 && (vref_sel_int_final===1'bx || vtrip_sel_final===1'bx))
|| (ibuf_sel_final===1 && vref_sel_int_final===1 && (vcchib!==1 || vohref_int!==1))
|| (ibuf_sel_final===1 && vref_sel_int_final===1 && vtrip_sel_final===0 && ^voh_sel_final[2:0]===1'bx))
vinref_tmp = 1'bx;
else
vinref_tmp = ibuf_sel_final===0 ? 1'bz : 1'b1;
end
assign #(startup_time_vinref,0) VINREF = vinref_tmp;
assign VINREF_DFT = dft_refgen_final===1 ? VINREF : (dft_refgen_final===0 ? 1'bz : 1'bx);
endmodule