blob: 400c5ab190c435def4533f495d5282cd1ae24b8d [file] [log] [blame]
// SPDX-FileCopyrightText: 2020 Efabless Corporation
//
// 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
//
// http://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
`default_nettype none
`timescale 1 ns / 1 ps
`define UNIT_DELAY #1
`define USE_POWER_PINS
`define SIM_TIME 100_000
`include "libs.ref/sky130_fd_io/verilog/sky130_fd_io.v"
`include "libs.ref/sky130_fd_io/verilog/sky130_ef_io.v"
`include "libs.ref/sky130_fd_io/verilog/sky130_ef_io__gpiov2_pad_wrapped.v"
`include "defines.v"
`ifdef GL
`include "gl/chip_io.v"
`else
`ifdef SPLIT_BUS
`include "ports.v"
`include "chip_io_split.v"
`else
`include "pads.v"
`include "mprj_io.v"
`include "chip_io.v"
`endif
`endif
module chip_io_tb;
wire clock_core;
reg clock;
wire rstb_h;
reg RSTB;
reg porb_h;
wire por_l;
wire gpio;
reg gpio_out_core;
reg gpio_inenb_core;
reg gpio_outenb_core;
wire flash_csb;
reg flash_csb_core;
reg flash_csb_ieb_core;
reg flash_csb_oeb_core;
wire flash_clk;
reg flash_clk_core;
reg flash_clk_ieb_core;
reg flash_clk_oeb_core;
wire flash_io0;
wire flash_io0_di_core;
reg flash_io0_do_core;
reg flash_io0_ieb_core;
reg flash_io0_oeb_core;
wire flash_io1;
wire flash_io1_di_core;
reg flash_io1_do_core;
reg flash_io1_ieb_core;
reg flash_io1_oeb_core;
wire gpio_in_core;
wire gpio_mode0_core;
wire gpio_mode1_core;
wire [`MPRJ_IO_PADS-1:0] mprj_io;
reg [`MPRJ_IO_PADS-1:0] mprj_io_inp_dis;
reg [`MPRJ_IO_PADS-1:0] mprj_io_oeb;
reg [`MPRJ_IO_PADS-1:0] mprj_io_ib_mode_sel;
reg [`MPRJ_IO_PADS-1:0] mprj_io_vtrip_sel;
reg [`MPRJ_IO_PADS-1:0] mprj_io_slow_sel;
reg [`MPRJ_IO_PADS-1:0] mprj_io_holdover;
reg [`MPRJ_IO_PADS-1:0] mprj_io_analog_en;
reg [`MPRJ_IO_PADS-1:0] mprj_io_analog_sel;
reg [`MPRJ_IO_PADS-1:0] mprj_io_analog_pol;
reg [`MPRJ_IO_PADS*3-1:0] mprj_io_dm;
reg [`MPRJ_IO_PADS-1:0] mprj_io_out;
wire [`MPRJ_IO_PADS-1:0] mprj_io_in;
wire [`MPRJ_IO_PADS-10:0] mprj_analog_io;
always #12.5 clock <= (clock === 1'b0);
initial begin
clock = 0;
porb_h = 0;
flash_csb_core = 0;
flash_csb_ieb_core = 1;
flash_csb_oeb_core = 0;
flash_clk_ieb_core = 1;
flash_clk_oeb_core = 0;
mprj_io_ib_mode_sel = {38{1'b0}};
mprj_io_vtrip_sel = {38{1'b0}};
mprj_io_slow_sel = {38{1'b0}};
mprj_io_holdover = {38{1'b0}};
mprj_io_analog_en = {38{1'b0}};
mprj_io_analog_sel = {38{1'b0}};
mprj_io_analog_pol = {38{1'b0}};
end
wire VDD3V3;
wire VDD1V8;
wire VSS;
assign VDD3V3 = power1;
assign VDD1V8 = power2;
assign VSS = 1'b0;
reg power1, power2;
initial begin
RSTB <= 1'b0;
porb_h <= 1'b0;
#500;
porb_h <= 1'b1;
#500;
RSTB <= 1'b1; // Release reset
#2000;
end
initial begin // Power-up sequence
power1 <= 1'b0;
power2 <= 1'b0;
#200;
power1 <= 1'b1;
#200;
power2 <= 1'b1;
end
initial begin
$dumpfile("chip_io.vcd");
$dumpvars(0, chip_io_tb);
#(`SIM_TIME);
$display("%c[1;31m",27);
$display ("Monitor: Timeout, Test Management Protect Failed");
$display("%c[0m",27);
$finish;
end
integer i;
reg [2:0] dm_all;
reg gpio_bit;
assign gpio = gpio_bit;
assign gpio_mode0_core = dm_all[0];
assign gpio_mode1_core = dm_all[1];
reg flash_io0_bit;
reg flash_io1_bit;
assign flash_io0 = flash_io0_bit;
assign flash_io1 = flash_io1_bit;
reg [`MPRJ_IO_PADS-1:0] mprj_io_bits;
assign mprj_io = mprj_io_bits;
initial begin
wait(RSTB == 1'b1); // wait for reset
#25;
// Clock & Reset Pads
if (clock !== clock_core) begin
$display("Error: Clock Pad Test Failed."); $finish;
end
if (RSTB !== rstb_h) begin
$display("Error: Reset Pad Test Failed."); $finish;
end
// Management GPIO Pad
gpio_bit = 1'b1;
gpio_out_core = 1'b0;
gpio_inenb_core = 1'b0;
gpio_outenb_core = 1'b1;
dm_all = 3'b001; // input-only
#25;
if (gpio_in_core !== gpio) begin
$display("Error: GPIO Pad Input Test Failed."); $finish;
end
gpio_bit = 1'bz;
gpio_out_core = 1'b1;
gpio_inenb_core = 1'b1;
gpio_outenb_core = 1'b0;
dm_all = 3'b110; // output-only
#25;
if (gpio_out_core !== gpio) begin
$display("Error: GPIO Pad Output Test Failed."); $finish;
end
// Flash Output Pads
flash_csb_core = 1'b1; // CSB Pad
#25;
if (flash_csb !== flash_csb_core) begin
$display("Error: Flash CSB Pad Test Failed."); $finish;
end
flash_clk_core = 1'b1; // CLK Pad
#25;
if (flash_clk !== flash_clk_core) begin
$display("Error: Flash CLK Pad Test Failed."); $finish;
end
// Flash Inout Pads
flash_io0_bit = 1'b1;
flash_io0_ieb_core = 1'b0; // Input
flash_io0_oeb_core = 1'b1;
#25;
if (flash_io0_di_core !== flash_io0_bit) begin
$display("Error: Flash io0 Pad Input Test Failed."); $finish;
end
flash_io0_bit = 1'bz;
flash_io0_do_core = 1'b1;
flash_io0_ieb_core = 1'b1;
flash_io0_oeb_core = 1'b0; // Output
#25
if (flash_io0 !== flash_io0_do_core) begin
$display("Error: Flash io0 Pad Output Test Failed."); $finish;
end
// User Project Pads - All Outputs
mprj_io_bits = {38{1'bz}};
mprj_io_out = {6'b10101, 32'hF0F0};
mprj_io_oeb = {38{1'b0}};
mprj_io_inp_dis = {38{1'b1}};
mprj_io_dm = {38*3{3'b110}};
#25;
if (mprj_io !== mprj_io_out) begin
$display("Error: User Project Pads Output Test Failed."); $finish;
end
// User Project Pads - All Inputs
mprj_io_bits = {6'b01010, 32'hFF0F};
mprj_io_out = {38{1'b0}};
mprj_io_oeb = {38{1'b1}};
mprj_io_inp_dis = {38{1'b0}};
mprj_io_dm = {38*3{3'b001}};
#25;
if (mprj_io_in !== mprj_io_bits) begin
$display("Error: User Project Pads Input Test Failed."); $finish;
end
// User Project Pads - All Bidirectional
mprj_io_bits = {6'b01010, 32'hF00F}; // drive input signal
mprj_io_out = {38{1'bz}};
mprj_io_oeb = {38{1'b1}};
mprj_io_inp_dis = {38{1'b0}};
mprj_io_dm = {38{3'b110}};
#25;
if (mprj_io_in !== mprj_io_bits) begin
$display("Error: User Project Pads Bidirectional Test Failed."); $finish;
end
mprj_io_bits = {38{1'bz}};
mprj_io_out = {6'b01110, 32'h0FF0}; // drive output signal
mprj_io_oeb = {38{1'b0}};
mprj_io_inp_dis = {38{1'b0}};
mprj_io_dm = {38{3'b110}};
#25;
if (mprj_io !== mprj_io_out) begin
$display("Error: User Project Pads Output Test Failed."); $finish;
end
$display("Success");
$display("Monitor: Chip IO Test Passed.");
#2000;
$finish;
end
assign por_l = ~porb_h;
chip_io uut (
// Package Pins
.vddio (VDD3V3),
.vssio (VSS),
.vdda (VDD3V3),
.vssa (VSS),
.vccd (VDD1V8),
.vssd (VSS),
.vdda1 (VDD3V3),
.vdda2 (VDD3V3),
.vssa1 (VSS),
.vssa2 (VSS),
.vccd1 (VDD1V8),
.vccd2 (VDD1V8),
.vssd1 (VSS),
.vssd2 (VSS),
.gpio(gpio),
.clock(clock),
.resetb(RSTB),
.flash_csb(flash_csb),
.flash_clk(flash_clk),
.flash_io0(flash_io0),
.flash_io1(flash_io1),
// SoC Core Interface
.porb_h(porb_h),
.por(por_l),
.resetb_core_h(rstb_h),
.clock_core(clock_core),
.gpio_out_core(gpio_out_core),
.gpio_in_core(gpio_in_core),
.gpio_mode0_core(gpio_mode0_core),
.gpio_mode1_core(gpio_mode1_core),
.gpio_outenb_core(gpio_outenb_core),
.gpio_inenb_core(gpio_inenb_core),
.flash_csb_core(flash_csb_core),
.flash_clk_core(flash_clk_core),
.flash_csb_oeb_core(flash_csb_oeb_core),
.flash_clk_oeb_core(flash_clk_oeb_core),
.flash_io0_oeb_core(flash_io0_oeb_core),
.flash_io1_oeb_core(flash_io1_oeb_core),
.flash_csb_ieb_core(flash_csb_ieb_core),
.flash_clk_ieb_core(flash_clk_ieb_core),
.flash_io0_ieb_core(flash_io0_ieb_core),
.flash_io1_ieb_core(flash_io1_ieb_core),
.flash_io0_do_core(flash_io0_do_core),
.flash_io1_do_core(flash_io1_do_core),
.flash_io0_di_core(flash_io0_di_core),
.flash_io1_di_core(flash_io1_di_core),
`ifdef SPLIT_BUS
`MPRJ_IO,
`MPRJ_IO_IN,
`MPRJ_IO_OUT,
`MPRJ_IO_OEB,
`MPRJ_IO_INP_DIS,
`MPRJ_IO_IB_MODE_SEL,
`MPRJ_IO_VTRIP_SEL,
`MPRJ_IO_SLOW_SEL,
`MPRJ_IO_HOLDOVER,
`MPRJ_IO_ANALOG_EN,
`MPRJ_IO_ANALOG_SEL,
`MPRJ_IO_ANALOG_POL,
`MPRJ_IO_DM,
`MPRJ_IO_ANALOG
`else
.mprj_io(mprj_io),
.mprj_io_in(mprj_io_in),
.mprj_io_out(mprj_io_out),
.mprj_io_oeb(mprj_io_oeb),
.mprj_io_inp_dis(mprj_io_inp_dis),
.mprj_io_ib_mode_sel(mprj_io_ib_mode_sel),
.mprj_io_vtrip_sel(mprj_io_vtrip_sel),
.mprj_io_slow_sel(mprj_io_slow_sel),
.mprj_io_holdover(mprj_io_holdover),
.mprj_io_analog_en(mprj_io_analog_en),
.mprj_io_analog_sel(mprj_io_analog_sel),
.mprj_io_analog_pol(mprj_io_analog_pol),
.mprj_io_dm(mprj_io_dm),
.mprj_analog_io(mprj_analog_io)
`endif
);
endmodule