Skip to content

Commit 6ddb362

Browse files
committed
[chip, gpio, dv] Added W1's and W0's pattern for GPIOs in in/out mode
Signed-off-by: Kinza Qamar <kqzaman@lowrisc.org>
1 parent 76175da commit 6ddb362

File tree

2 files changed

+126
-2
lines changed

2 files changed

+126
-2
lines changed

hw/top_chip/dv/env/seq_lib/top_chip_dv_gpio_base_vseq.sv

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ class top_chip_dv_gpio_base_vseq extends top_chip_dv_base_vseq;
88
// Standard SV/UVM methods
99
extern function new(string name = "");
1010
extern task body();
11+
extern virtual task gpio_output_test();
12+
extern virtual task gpio_input_test();
1113
endclass : top_chip_dv_gpio_base_vseq
1214

1315
function top_chip_dv_gpio_base_vseq::new (string name = "");
@@ -17,5 +19,77 @@ endfunction : new
1719
task top_chip_dv_gpio_base_vseq::body();
1820
super.body();
1921
`DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInTest);
20-
// TODO
22+
gpio_output_test();
23+
gpio_input_test();
2124
endtask : body
25+
26+
task top_chip_dv_gpio_base_vseq::gpio_output_test();
27+
// Disable GPIOs from being driven as chip inputs.
28+
cfg.gpio_vif.drive_en({NUM_GPIOS{1'b0}});
29+
30+
`uvm_info(`gfn, "Starting GPIO output test", UVM_LOW)
31+
32+
// Wait and check all 0s.
33+
`DV_SPINWAIT(wait(cfg.gpio_vif.pins === {NUM_GPIOS{1'b0}});,
34+
$sformatf("Timed out waiting for GPIOs == %0h", {NUM_GPIOS{1'b0}}),
35+
/*use default_spinwait_timeout_ns*/,
36+
`gfn)
37+
38+
// Check for W1 pattern on the GPIO output pins.
39+
for (int i = 0; i < NUM_GPIOS; i++) begin
40+
logic [NUM_GPIOS-1:0] exp_gpios = 1 << i;
41+
`DV_SPINWAIT(wait(cfg.gpio_vif.pins === exp_gpios);,
42+
$sformatf("Timed out waiting for GPIOs == %0h", exp_gpios),
43+
/*use default_spinwait_timeout_ns*/,
44+
`gfn)
45+
end
46+
47+
// Wait and check all 1s.
48+
`DV_SPINWAIT(wait(cfg.gpio_vif.pins === {NUM_GPIOS{1'b1}});,
49+
$sformatf("Timed out waiting for GPIOs == %0h", {NUM_GPIOS{1'b1}}),
50+
/*use default_spinwait_timeout_ns*/,
51+
`gfn)
52+
53+
// Check for W0 pattern on the GPIO output pins.
54+
for (int i = 0; i < NUM_GPIOS; i++) begin
55+
logic [NUM_GPIOS-1:0] exp_gpios = ~(1 << i);
56+
`DV_SPINWAIT(wait(cfg.gpio_vif.pins === exp_gpios);,
57+
$sformatf("Timed out waiting for GPIOs == %0h", exp_gpios),
58+
/*use default_spinwait_timeout_ns*/,
59+
`gfn)
60+
end
61+
endtask : gpio_output_test
62+
63+
task top_chip_dv_gpio_base_vseq::gpio_input_test();
64+
// Wait and check all zs - this indicates it is safe to drive GPIOs as inputs.
65+
`DV_SPINWAIT(wait(cfg.gpio_vif.pins === {NUM_GPIOS{1'bZ}});,
66+
$sformatf("Timed out waiting for GPIOs == %0h", {NUM_GPIOS{1'bZ}}),
67+
/*use default_spinwait_timeout_ns*/,
68+
`gfn)
69+
70+
cfg.peri_clk_vif.wait_clks(1);
71+
72+
cfg.gpio_vif.drive({NUM_GPIOS{1'b0}});
73+
74+
cfg.peri_clk_vif.wait_clks(1);
75+
76+
`uvm_info(`gfn, "Starting GPIO input test", UVM_LOW)
77+
78+
// Drive W1 pattern
79+
for (int i = 0; i < NUM_GPIOS; i++) begin
80+
cfg.gpio_vif.drive(1 << i);
81+
cfg.peri_clk_vif.wait_clks(1);
82+
end
83+
84+
cfg.gpio_vif.drive({NUM_GPIOS{1'b1}});
85+
86+
cfg.peri_clk_vif.wait_clks(1);
87+
88+
`uvm_info(`gfn, "Starting GPIO input test", UVM_LOW)
89+
90+
// Drive W0 pattern
91+
for (int i = 0; i < NUM_GPIOS; i++) begin
92+
cfg.gpio_vif.drive(~(1 << i));
93+
cfg.peri_clk_vif.wait_clks(1);
94+
end
95+
endtask : gpio_input_test

sw/device/tests/gpio/smoketest.c

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,58 @@ static bool reg_test(gpio_t gpio)
4949
return true;
5050
}
5151

52+
// Verifies GPIOs pins in output direction. This will walk 1's followed by 0's on GPIOs when output
53+
// mode is enabled.
54+
static bool output_test(gpio_t gpio)
55+
{
56+
// Enable the GPIOs in output mode
57+
gpio_set_all_oe(gpio, 0xFFFFFFFF);
58+
59+
// Step-1: Set the gpios to all 0s in order to walk 1 on each pin.
60+
gpio_write(gpio, 0x0);
61+
62+
// Step-2: Walk 1 on each pin now and read "data_in" reg on each write to ensure correctness.
63+
for (int i = 0; i < GPIO_NUM_PINS; i++) {
64+
uint32_t write_val = 1 << i;
65+
gpio_write(gpio, write_val);
66+
if (write_val != DEV_READ(gpio + GPIO_REG_DATA_IN)) {
67+
return false;
68+
}
69+
}
70+
71+
// Step-3: Set the gpios to all 1s in order to walk 0 on each pin.
72+
gpio_write(gpio, 0xFFFFFFFF);
73+
74+
// Step-4: Walk 0 on each pin now and read "data_in" reg on each write to ensure correctness.
75+
for (int i = 0; i < GPIO_NUM_PINS; i++) {
76+
uint32_t write_val = ~(1 << i);
77+
gpio_write(gpio, write_val);
78+
if (write_val != DEV_READ(gpio + GPIO_REG_DATA_IN)) {
79+
return false;
80+
}
81+
}
82+
83+
return true;
84+
}
85+
86+
// Verifies GPIOs pins in input direction. This will walk 1's followed by 0's on GPIOs when input
87+
// mode is enabled.
88+
static bool input_test(gpio_t gpio)
89+
{
90+
// Enable the GPIOs in input mode
91+
gpio_set_all_oe(gpio, 0x0);
92+
for (int i = 0; i < GPIO_NUM_PINS; i++) {
93+
uint32_t write_val = 1 << i;
94+
if (write_val != DEV_READ(gpio + GPIO_REG_DATA_IN)) {
95+
return false;
96+
}
97+
}
98+
return true;
99+
}
100+
52101
bool test_main()
53102
{
54103
gpio_t gpio = mocha_system_gpio();
55-
return reg_test(gpio);
104+
return (output_test(gpio) & input_test(gpio));
105+
// return input_test(gpio);
56106
}

0 commit comments

Comments
 (0)