| /* |
| * 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_xres4v2 ( TIE_WEAK_HI_H, XRES_H_N, TIE_HI_ESD, TIE_LO_ESD, |
| AMUXBUS_A, AMUXBUS_B, PAD, PAD_A_ESD_H, ENABLE_H, EN_VDDIO_SIG_H, INP_SEL_H, FILT_IN_H, |
| DISABLE_PULLUP_H, PULLUP_H, ENABLE_VDDIO |
| ); |
| wire mode_vcchib; |
| output XRES_H_N; |
| inout AMUXBUS_A; |
| inout AMUXBUS_B; |
| inout PAD; |
| input DISABLE_PULLUP_H; |
| input ENABLE_H; |
| input EN_VDDIO_SIG_H; |
| input INP_SEL_H; |
| input FILT_IN_H; |
| inout PULLUP_H; |
| input ENABLE_VDDIO; |
| supply1 vccd; |
| supply1 vcchib; |
| supply1 vdda; |
| supply1 vddio; |
| supply1 vddio_q; |
| supply0 vssa; |
| supply0 vssd; |
| supply0 vssio; |
| supply0 vssio_q; |
| supply1 vswitch; |
| wire pwr_good_xres_tmp = 1; |
| wire pwr_good_xres_h_n = 1; |
| wire pwr_good_pullup = 1; |
| inout PAD_A_ESD_H; |
| output TIE_HI_ESD; |
| output TIE_LO_ESD; |
| inout TIE_WEAK_HI_H; |
| wire tmp1; |
| pullup (pull1) p1 (tmp1); tranif1 x_pull_1 (TIE_WEAK_HI_H, tmp1, pwr_good_pullup===0 ? 1'bx : 1); |
| tran p2 (PAD, PAD_A_ESD_H); |
| buf p4 (TIE_HI_ESD, vddio); |
| buf p5 (TIE_LO_ESD, vssio); |
| wire tmp; |
| pullup (pull1) p3 (tmp); tranif0 x_pull (PULLUP_H, tmp, pwr_good_pullup===0 || ^DISABLE_PULLUP_H===1'bx ? 1'bx : DISABLE_PULLUP_H); |
| parameter MAX_WARNING_COUNT = 100; |
| `ifdef SKY130_FD_IO_TOP_XRES4V2_DISABLE_DELAY |
| parameter MIN_DELAY = 0; |
| parameter MAX_DELAY = 0; |
| `else |
| parameter MIN_DELAY = 50; |
| parameter MAX_DELAY = 600; |
| `endif |
| integer min_delay, max_delay; |
| initial begin |
| min_delay = MIN_DELAY; |
| max_delay = MAX_DELAY; |
| end |
| `ifdef SKY130_FD_IO_TOP_XRES4V2_DISABLE_ENABLE_VDDIO_CHANGE_X |
| parameter DISABLE_ENABLE_VDDIO_CHANGE_X = 1; |
| `else |
| parameter DISABLE_ENABLE_VDDIO_CHANGE_X = 0; |
| `endif |
| integer disable_enable_vddio_change_x = DISABLE_ENABLE_VDDIO_CHANGE_X; |
| reg notifier_enable_h; |
| specify |
| `ifdef SKY130_FD_IO_TOP_XRES4V2_DISABLE_DELAY |
| specparam DELAY = 0; |
| `else |
| specparam DELAY = 50; |
| `endif |
| if (INP_SEL_H==0 & ENABLE_H==0 & ENABLE_VDDIO==0 & EN_VDDIO_SIG_H==1) (PAD => XRES_H_N) = (0:0:0 , 0:0:0); |
| if (INP_SEL_H==0 & ENABLE_H==1 & ENABLE_VDDIO==1 & EN_VDDIO_SIG_H==1) (PAD => XRES_H_N) = (0:0:0 , 0:0:0); |
| if (INP_SEL_H==0 & ENABLE_H==1 & ENABLE_VDDIO==1 & EN_VDDIO_SIG_H==0) (PAD => XRES_H_N) = (0:0:0 , 0:0:0); |
| if (INP_SEL_H==0 & ENABLE_H==0 & ENABLE_VDDIO==0 & EN_VDDIO_SIG_H==0) (PAD => XRES_H_N) = (0:0:0 , 0:0:0); |
| if (INP_SEL_H==1) (FILT_IN_H => XRES_H_N) = (0:0:0 , 0:0:0); |
| specparam tsetup = 0; |
| specparam thold = 5; |
| endspecify |
| reg corrupt_enable; |
| always @(notifier_enable_h) |
| begin |
| corrupt_enable <= 1'bx; |
| end |
| initial |
| begin |
| corrupt_enable = 1'b0; |
| end |
| always @(PAD or ENABLE_H or EN_VDDIO_SIG_H or ENABLE_VDDIO or INP_SEL_H or FILT_IN_H or pwr_good_xres_tmp or DISABLE_PULLUP_H or PULLUP_H or TIE_WEAK_HI_H) |
| begin |
| corrupt_enable <= 1'b0; |
| end |
| assign mode_vcchib = ENABLE_H && !EN_VDDIO_SIG_H; |
| wire xres_tmp = (pwr_good_xres_tmp===0 || ^PAD===1'bx || (mode_vcchib===1'bx ) ||(mode_vcchib!==1'b0 && ^ENABLE_VDDIO===1'bx) || (corrupt_enable===1'bx) || |
| (mode_vcchib===1'b1 && ENABLE_VDDIO===0 && (disable_enable_vddio_change_x===0))) |
| ? 1'bx : PAD; |
| wire x_on_xres_h_n = (pwr_good_xres_h_n===0 |
| || ^INP_SEL_H===1'bx |
| || INP_SEL_H===1 && ^FILT_IN_H===1'bx |
| || INP_SEL_H===0 && xres_tmp===1'bx); |
| assign #1 XRES_H_N = x_on_xres_h_n===1 ? 1'bx : (INP_SEL_H===1 ? FILT_IN_H : xres_tmp); |
| realtime t_pad_current_transition,t_pad_prev_transition; |
| realtime t_filt_in_h_current_transition,t_filt_in_h_prev_transition; |
| realtime pad_pulse_width, filt_in_h_pulse_width; |
| always @(PAD) |
| begin |
| if (^PAD !== 1'bx) |
| begin |
| t_pad_prev_transition = t_pad_current_transition; |
| t_pad_current_transition = $realtime; |
| pad_pulse_width = t_pad_current_transition - t_pad_prev_transition; |
| end |
| else |
| begin |
| t_pad_prev_transition = 0; |
| t_pad_current_transition = 0; |
| pad_pulse_width = 0; |
| end |
| end |
| always @(FILT_IN_H) |
| begin |
| if (^FILT_IN_H !== 1'bx) |
| begin |
| t_filt_in_h_prev_transition = t_filt_in_h_current_transition; |
| t_filt_in_h_current_transition = $realtime; |
| filt_in_h_pulse_width = t_filt_in_h_current_transition - t_filt_in_h_prev_transition; |
| end |
| else |
| begin |
| t_filt_in_h_prev_transition = 0; |
| t_filt_in_h_current_transition = 0; |
| filt_in_h_pulse_width = 0; |
| end |
| end |
| reg dis_err_msgs; |
| integer msg_count_pad, msg_count_filt_in_h; |
| event event_errflag_pad_pulse_width, event_errflag_filt_in_h_pulse_width; |
| initial |
| begin |
| dis_err_msgs = 1'b1; |
| msg_count_pad = 0; msg_count_filt_in_h = 0; |
| `ifdef SKY130_FD_IO_TOP_XRES4V2_DIS_ERR_MSGS |
| `else |
| #1; |
| dis_err_msgs = 1'b0; |
| `endif |
| end |
| always @(pad_pulse_width) |
| begin |
| if (!dis_err_msgs) |
| begin |
| if (INP_SEL_H===0 && (pad_pulse_width > min_delay) && (pad_pulse_width < max_delay)) |
| begin |
| msg_count_pad = msg_count_pad + 1; |
| ->event_errflag_pad_pulse_width; |
| if (msg_count_pad <= MAX_WARNING_COUNT) |
| begin |
| $display(" ===WARNING=== sky130_fd_io__top_xres4v2 : Width of Input pulse for PAD input (= %3.2f ns) is found to be in \the range: %3d ns - %3d ns. In this range, the delay and pulse suppression of the input pulse are PVT dependent. : \%m",pad_pulse_width,min_delay,max_delay,$stime); |
| end |
| else |
| if (msg_count_pad == MAX_WARNING_COUNT+1) |
| begin |
| $display(" ===WARNING=== sky130_fd_io__top_xres4v2 : Further WARNING messages will be suppressed as the \message count has exceeded 100 %m",$stime); |
| end |
| end |
| end |
| end |
| always @(filt_in_h_pulse_width) |
| begin |
| if (!dis_err_msgs) |
| begin |
| if (INP_SEL_H===1 && (filt_in_h_pulse_width > min_delay) && (filt_in_h_pulse_width < max_delay)) |
| begin |
| msg_count_filt_in_h = msg_count_filt_in_h + 1; |
| ->event_errflag_filt_in_h_pulse_width; |
| if (msg_count_filt_in_h <= MAX_WARNING_COUNT) |
| begin |
| $display(" ===WARNING=== sky130_fd_io__top_xres4v2 : Width of Input pulse for FILT_IN_H input (= %3.2f ns) is found to be in \the range: %3d ns - %3d ns. In this range, the delay and pulse suppression of the input pulse are PVT dependent. : \%m",filt_in_h_pulse_width,min_delay,max_delay,$stime); |
| end |
| else |
| if (msg_count_filt_in_h == MAX_WARNING_COUNT+1) |
| begin |
| $display(" ===WARNING=== sky130_fd_io__top_xres4v2 : Further WARNING messages will be suppressed as the \message count has exceeded 100 %m",$stime); |
| end |
| end |
| end |
| end |
| endmodule |