Files
retroSoC/tests/rtl/tc_pdk_cells_tb.sv
T
maksyuki 942ca936bf feat: Add IHP130 support and enhance power pin handling
- Updated filelist to include sg13g2_udp.v for IHP130.
- Modified sdram_axi4.sv to initialize read and write control signals.
- Enhanced clock and reset domain configuration to include jtag_trst_n_i_pad.
- Updated iverilog.mk to support IHP130 in tech-cell-test.
- Enhanced pin_map generation to include power pads for IHP130.
- Updated tc_io modules to handle power pins for IHP130.
- Added timing contract generation in package.py for commercial flow.
- Enhanced test cases to validate new IHP130 features and configurations.
- Added new tests for LibreLane flow specific to IHP130.
2026-08-23 22:27:04 +08:00

358 lines
8.3 KiB
Systemverilog

`timescale 1ns / 1ps
module tc_pdk_cells_tb;
`ifdef USE_POWER_PINS
wire iovdd = 1'b1;
wire iovss = 1'b0;
wire vdd = 1'b1;
wire vss = 1'b0;
`endif
logic in_drive;
logic in_drive_en;
tri in_pad;
logic in_p2c;
logic out_c2p;
tri out_pad;
logic tri_c2p;
logic tri_c2p_en;
logic tri_drive;
logic tri_drive_en;
tri tri_pad;
logic tri_p2c;
logic schmitt_c2p;
logic schmitt_c2p_en;
logic schmitt_drive;
logic schmitt_drive_en;
tri schmitt_pad;
logic schmitt_p2c;
logic full_c2p;
logic full_c2p_en;
logic full_drive;
logic full_drive_en;
logic full_cs;
logic full_pu;
logic full_pd;
tri full_pad;
logic full_p2c;
logic clk0_i;
logic clk1_i;
logic clk_sel_i;
logic clk_inv_o;
logic clk_buf_o;
logic clk_mux_o;
logic clk_xor_o;
`ifdef PDK_GF180
logic gf180_seq_clk;
logic gf180_seq_d;
logic gf180_seq_reset_n;
logic gf180_dffq_q;
logic gf180_dffrnq_q;
logic gf180_dffsnq_q;
gf180mcu_fd_sc_mcu7t5v0__dffq_1 u_gf180_dffq (
.CLK (gf180_seq_clk),
.D (gf180_seq_d),
.Q (gf180_dffq_q),
.notifier()
);
gf180mcu_fd_sc_mcu7t5v0__dffrnq_1 u_gf180_dffrnq (
.CLK (gf180_seq_clk),
.D (gf180_seq_d),
.RN (gf180_seq_reset_n),
.Q (gf180_dffrnq_q),
.notifier()
);
gf180mcu_fd_sc_mcu7t5v0__dffsnq_1 u_gf180_dffsnq (
.CLK (gf180_seq_clk),
.D (gf180_seq_d),
.SETN (gf180_seq_reset_n),
.Q (gf180_dffsnq_q),
.notifier()
);
`endif
`ifdef PDK_ICS55
logic ics55_od_i;
logic ics55_od_oe;
logic ics55_od_mode;
logic ics55_pu;
logic ics55_pd;
tri ics55_pad;
logic [2:0] ics55_mux_inputs;
logic ics55_mux_y;
P65_1233_PBMUX u_ics55_open_drain_pad (
.C (),
.A (),
.PAD(ics55_pad),
.IE (1'b0),
.CS (1'b1),
.I (ics55_od_i),
.OE (ics55_od_oe),
.OD (ics55_od_mode),
.PU (ics55_pu),
.PD (ics55_pd),
.DS0(1'b0),
.DS1(1'b1)
);
MUXI2X0P5H7R u_ics55_muxi2 (
.A (ics55_mux_inputs[0]),
.B (ics55_mux_inputs[1]),
.S0(ics55_mux_inputs[2]),
.Y (ics55_mux_y)
);
`endif
assign in_pad = in_drive_en ? in_drive : 1'bz;
assign tri_pad = tri_drive_en ? tri_drive : 1'bz;
assign schmitt_pad = schmitt_drive_en ? schmitt_drive : 1'bz;
assign full_pad = full_drive_en ? full_drive : 1'bz;
tc_io_in_pad u_tc_io_in_pad (
`ifdef USE_POWER_PINS
.iovdd(iovdd),
.iovss(iovss),
.vdd (vdd),
.vss (vss),
`endif
.pad (in_pad),
.p2c (in_p2c)
);
tc_io_out_pad u_tc_io_out_pad (
`ifdef USE_POWER_PINS
.iovdd(iovdd),
.iovss(iovss),
.vdd (vdd),
.vss (vss),
`endif
.pad (out_pad),
.c2p (out_c2p)
);
tc_io_tri_pad u_tc_io_tri_pad (
`ifdef USE_POWER_PINS
.iovdd (iovdd),
.iovss (iovss),
.vdd (vdd),
.vss (vss),
`endif
.pad (tri_pad),
.c2p (tri_c2p),
.c2p_en(tri_c2p_en),
.p2c (tri_p2c)
);
tc_io_tri_schmitt_pad u_tc_io_tri_schmitt_pad (
`ifdef USE_POWER_PINS
.iovdd (iovdd),
.iovss (iovss),
.vdd (vdd),
.vss (vss),
`endif
.pad (schmitt_pad),
.c2p (schmitt_c2p),
.c2p_en(schmitt_c2p_en),
.p2c (schmitt_p2c)
);
tc_io_tri_full_pad u_tc_io_tri_full_pad (
`ifdef USE_POWER_PINS
.iovdd (iovdd),
.iovss (iovss),
.vdd (vdd),
.vss (vss),
`endif
.pad (full_pad),
.c2p (full_c2p),
.c2p_en(full_c2p_en),
.p2c (full_p2c),
.cs (full_cs),
.pu (full_pu),
.pd (full_pd)
);
tc_clk_inv u_tc_clk_inv (
.clk_i(clk0_i),
.clk_o(clk_inv_o)
);
tc_clk_buf u_tc_clk_buf (
.clk_i(clk0_i),
.clk_o(clk_buf_o)
);
tc_clk_mux2 u_tc_clk_mux2 (
.clk0_i (clk0_i),
.clk1_i (clk1_i),
.clk_sel_i(clk_sel_i),
.clk_o (clk_mux_o)
);
tc_clk_xor2 u_tc_clk_xor2 (
.clk0_i(clk0_i),
.clk1_i(clk1_i),
.clk_o (clk_xor_o)
);
task automatic expect_bit(input logic actual, input logic expected, input string message);
if (actual !== expected) begin
$fatal(1, "%s: expected %b, got %b", message, expected, actual);
end
endtask
initial begin
in_drive = 1'b0;
in_drive_en = 1'b0;
out_c2p = 1'b0;
tri_c2p = 1'b0;
tri_c2p_en = 1'b0;
tri_drive = 1'b0;
tri_drive_en = 1'b0;
schmitt_c2p = 1'b0;
schmitt_c2p_en = 1'b0;
schmitt_drive = 1'b0;
schmitt_drive_en = 1'b0;
full_c2p = 1'b0;
full_c2p_en = 1'b0;
full_drive = 1'b0;
full_drive_en = 1'b0;
full_cs = 1'b0;
full_pu = 1'b0;
full_pd = 1'b0;
clk0_i = 1'b0;
clk1_i = 1'b1;
clk_sel_i = 1'b0;
`ifdef PDK_GF180
gf180_seq_clk = 1'b0;
gf180_seq_d = 1'b0;
gf180_seq_reset_n = 1'b0;
`endif
`ifdef PDK_ICS55
ics55_od_i = 1'b1;
ics55_od_oe = 1'b0;
ics55_od_mode = 1'b1;
ics55_pu = 1'b0;
ics55_pd = 1'b0;
ics55_mux_inputs = 3'b000;
`endif
#5;
in_drive_en = 1'b1;
in_drive = 1'b1;
#5;
expect_bit(in_p2c, 1'b1, "input pad propagation");
out_c2p = 1'b1;
#5;
expect_bit(out_pad, 1'b1, "output pad high drive");
out_c2p = 1'b0;
#5;
expect_bit(out_pad, 1'b0, "output pad low drive");
tri_drive_en = 1'b1;
tri_drive = 1'b1;
#5;
expect_bit(tri_p2c, 1'b1, "tri-state pad input");
tri_drive_en = 1'b0;
tri_c2p = 1'b1;
tri_c2p_en = 1'b1;
#5;
expect_bit(tri_pad, 1'b1, "tri-state pad output");
`ifdef PDK_ICS55
expect_bit(tri_p2c, 1'b0, "ICS55 tri-state output disables input receiver");
`else
expect_bit(tri_p2c, 1'b1, "tri-state output readback");
`endif
tri_c2p_en = 1'b0;
#5;
if (tri_pad !== 1'bz) begin
$fatal(1, "tri-state pad did not release the line");
end
schmitt_drive_en = 1'b1;
schmitt_drive = 1'b1;
#5;
expect_bit(schmitt_p2c, 1'b1, "Schmitt pad input");
schmitt_drive_en = 1'b0;
schmitt_c2p = 1'b1;
schmitt_c2p_en = 1'b1;
#5;
expect_bit(schmitt_pad, 1'b1, "Schmitt pad output");
full_drive_en = 1'b1;
full_drive = 1'b1;
full_cs = 1'b1;
#5;
expect_bit(full_p2c, 1'b1, "full pad input");
full_drive_en = 1'b0;
full_c2p = 1'b1;
full_c2p_en = 1'b1;
#5;
expect_bit(full_pad, 1'b1, "full pad output");
#5;
expect_bit(clk_inv_o, 1'b1, "clock inverter");
expect_bit(clk_buf_o, 1'b0, "clock buffer");
expect_bit(clk_mux_o, 1'b0, "clock mux select zero");
expect_bit(clk_xor_o, 1'b1, "clock xor");
clk_sel_i = 1'b1;
clk0_i = 1'b1;
clk1_i = 1'b0;
#5;
expect_bit(clk_inv_o, 1'b0, "clock inverter toggle");
expect_bit(clk_buf_o, 1'b1, "clock buffer toggle");
expect_bit(clk_mux_o, 1'b0, "clock mux select one");
expect_bit(clk_xor_o, 1'b1, "clock xor toggle");
`ifdef PDK_GF180
expect_bit(gf180_dffrnq_q, 1'b0, "GF180 reset-low DFF");
expect_bit(gf180_dffsnq_q, 1'b1, "GF180 reset-high DFF");
gf180_seq_reset_n = 1'b1;
gf180_seq_d = 1'b1;
gf180_seq_clk = 1'b1;
#5;
expect_bit(gf180_dffq_q, 1'b1, "GF180 DFF clock capture");
expect_bit(gf180_dffrnq_q, 1'b1, "GF180 reset-low DFF clock capture");
expect_bit(gf180_dffsnq_q, 1'b1, "GF180 reset-high DFF clock capture");
`endif
`ifdef PDK_ICS55
ics55_od_oe = 1'b1;
#5;
if (ics55_pad !== 1'bz) begin
$fatal(1, "ICS55 open-drain pad did not release high data");
end
ics55_od_i = 1'b0;
#5;
expect_bit(ics55_pad, 1'b0, "ICS55 open-drain low drive");
ics55_od_oe = 1'b0;
ics55_pu = 1'b1;
#5;
expect_bit(ics55_pad, 1'b1, "ICS55 pull-up");
ics55_pu = 1'b0;
ics55_pd = 1'b1;
#5;
expect_bit(ics55_pad, 1'b0, "ICS55 pull-down");
for (int mux_vector = 0; mux_vector < 8; mux_vector++) begin
ics55_mux_inputs = mux_vector[2:0];
#1;
expect_bit(ics55_mux_y, ~(ics55_mux_inputs[2] ? ics55_mux_inputs[1] : ics55_mux_inputs[0]),
$sformatf("ICS55 MUXI2 vector %0d", mux_vector));
end
`endif
$display("technology IO and clock cell test passed");
$finish;
end
endmodule