mirror of https://github.com/efabless/caravel.git
378 lines
10 KiB
Verilog
378 lines
10 KiB
Verilog
// 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
|