mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-06 14:55:14 +00:00
- 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.
358 lines
8.3 KiB
Systemverilog
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
|