Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions hw/top_chip/dv/env/seq_lib/top_chip_dv_gpio_smoke_vseq.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright lowRISC contributors (COSMIC project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

class top_chip_dv_gpio_smoke_vseq extends top_chip_dv_base_vseq;
`uvm_object_utils(top_chip_dv_gpio_smoke_vseq)

// Standard SV/UVM methods
extern function new(string name="");
extern task body();

// Class specific methods
//
// Wait for the pattern to appear on the GPIO's pads
extern virtual task wait_for_pattern(logic [NUM_GPIOS-1:0] exp_val);
endclass : top_chip_dv_gpio_smoke_vseq

function top_chip_dv_gpio_smoke_vseq::new (string name = "");
super.new(name);
endfunction : new

task top_chip_dv_gpio_smoke_vseq::body();
super.body();
`DV_WAIT(cfg.sw_test_status_vif.sw_test_status == SwTestStatusInTest);

`uvm_info(`gfn, "Starting GPIOs outputs test", UVM_LOW)

// SW first drives walking 1's on each pin. Wait till those patterns are visible
for (int i = 0; i < NUM_GPIOS; i++) begin
wait_for_pattern(1 << i);
end

// Wait for Z so that the pads can safely be driven in inputs
wait_for_pattern('Z);

// The outputs on the pads are seen on the edge of sys_clk_if.clk so wait at least a negedge
// before driving the pads in inputs.
cfg.sys_clk_vif.wait_n_clks(1);

`uvm_info(`gfn, "Starting GPIOs inputs test", UVM_LOW)

// Drive the pads as inputs
cfg.gpio_vif.drive('h5555_5555);
endtask : body

task top_chip_dv_gpio_smoke_vseq::wait_for_pattern(logic [NUM_GPIOS-1:0] exp_val);
`DV_SPINWAIT(wait(cfg.gpio_vif.pins === exp_val);,
$sformatf("Timed out waiting for GPIOs == %0h", exp_val))
endtask : wait_for_pattern
1 change: 1 addition & 0 deletions hw/top_chip/dv/env/seq_lib/top_chip_dv_vseq_list.sv
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@

`include "top_chip_dv_base_vseq.sv"
`include "top_chip_dv_uart_base_vseq.sv"
`include "top_chip_dv_gpio_smoke_vseq.sv"
2 changes: 2 additions & 0 deletions hw/top_chip/dv/env/top_chip_dv_env.core
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ filesets:
- lowrisc:dv:mem_bkdr_util
- lowrisc:dv:uart_agent
- lowrisc:dv:common_ifs
- lowrisc:mocha_dv:gpio_env
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks reasonable, but I noticed that the first commit adds gpio_env as a direct dependency of the sim. Can we drop it from there, maybe?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No then the environment is unable to find NUM_GPIOS. There must be a dependency mess-up because I just saw in build.log that it is unable to find top_chip_dv_env_pkg

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I spent a while to make it work somehow. The problem atm is that I want to use NUM_GPIOS parameter from gpio_env_pkg in tb.sv and uvm. I have an import import gpio_env_pkg::NUM_GPIOS; in top_chip_dv_env_pkg to be able to use that parameter in UVM. To achieve that I need to have - lowrisc:mocha_dv:gpio_env in top_chip_dv_env.core

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. I think that the dependency chain should be:

  1. The sim core contains tb.sv.
  2. That sim core depends on the chip-level test.
  3. The test depends on the chip-level environment.
  4. The chip-level environment depends on the block-level environments for the various blocks.

But I just looked and I don't think lowrisc:mocha_dv:top_chip_sim depends on lowrisc:mocha_dv:top_chip_dv_test. This is a bug! (I'd probably suggest opening a 1-line PR to put in the dependency, which can land before this PR)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be a bug indeed, I struggled a bit to set the core files

files:
- top_chip_dv_env_pkg.sv
- mem_clear_util.sv: {is_include_file: true}
Expand All @@ -22,6 +23,7 @@ filesets:
- seq_lib/top_chip_dv_vseq_list.sv: {is_include_file: true}
- seq_lib/top_chip_dv_base_vseq.sv: {is_include_file: true}
- seq_lib/top_chip_dv_uart_base_vseq.sv: {is_include_file: true}
- seq_lib/top_chip_dv_gpio_smoke_vseq.sv: {is_include_file: true}
file_type: systemVerilogSource

targets:
Expand Down
5 changes: 5 additions & 0 deletions hw/top_chip/dv/env/top_chip_dv_env.sv
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ function void top_chip_dv_env::build_phase(uvm_phase phase);
`uvm_fatal(`gfn, "failed to get sw_logger_vif from uvm_config_db")
end

// Get the GPIO VIF handle
if (!uvm_config_db#(virtual pins_if #(NUM_GPIOS))::get(this, "", "gpio_vif", cfg.gpio_vif)) begin
`uvm_fatal(`gfn, "Failed to retrieve gpio_vif from uvm_config_db")
end

// Initialize the sw logger interface.
foreach (cfg.mem_image_files[i]) begin
if (i inside {ChipMemSRAM}) begin
Expand Down
4 changes: 4 additions & 0 deletions hw/top_chip/dv/env/top_chip_dv_env_cfg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ class top_chip_dv_env_cfg extends uvm_object;
// External interfaces
virtual clk_rst_if sys_clk_vif;
virtual clk_rst_if peri_clk_vif;

// GPIO Pads interface
virtual pins_if #(NUM_GPIOS) gpio_vif;

// Software logging & status interfaces
virtual sw_logger_if sw_logger_vif;
virtual sw_test_status_if sw_test_status_vif;
Expand Down
1 change: 1 addition & 0 deletions hw/top_chip/dv/env/top_chip_dv_env_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package top_chip_dv_env_pkg;
import mem_bkdr_util_pkg::*;
import sw_test_status_pkg::*;
import uart_agent_pkg::*;
import gpio_env_pkg::NUM_GPIOS;

// Macro includes
`include "uvm_macros.svh"
Expand Down
16 changes: 16 additions & 0 deletions hw/top_chip/dv/tb/tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module tb;
import mem_bkdr_util_pkg::mem_bkdr_util;
import top_chip_dv_env_pkg::*;
import top_chip_dv_test_pkg::*;
import gpio_env_pkg::NUM_GPIOS;

import top_chip_dv_env_pkg::SW_DV_START_ADDR;
import top_chip_dv_env_pkg::SW_DV_TEST_STATUS_ADDR;
Expand All @@ -25,6 +26,9 @@ module tb;
wire rst_n;
wire peri_clk;
wire peri_rst_n;
wire [NUM_GPIOS-1:0] gpio_pads; // A wire connected to bidirectional pads in pins_if
logic [NUM_GPIOS-1:0] dut_gpio_o;
logic [NUM_GPIOS-1:0] dut_gpio_en_o;

logic [3:0] spi_host_sd;
logic [3:0] spi_host_sd_en;
Expand All @@ -33,6 +37,7 @@ module tb;
clk_rst_if sys_clk_if(.clk(clk), .rst_n(rst_n));
clk_rst_if peri_clk_if(.clk(peri_clk), .rst_n(peri_rst_n));
uart_if uart_if();
pins_if #(NUM_GPIOS) gpio_if (.pins(gpio_pads));

// ------ Mock DRAM ------
top_pkg::axi_dram_req_t dram_req;
Expand All @@ -52,6 +57,10 @@ module tb;
// Clock and reset.
.clk_i (clk ),
.rst_ni (rst_n ),
// GPIO inputs and outputs with output enable
.gpio_i (gpio_pads ),
.gpio_o (dut_gpio_o ),
.gpio_en_o (dut_gpio_en_o ),
// UART receive and transmit.
.uart_rx_i (uart_if.uart_rx ),
.uart_tx_o (uart_if.uart_tx ),
Expand Down Expand Up @@ -86,6 +95,12 @@ module tb;
.dram_resp_i (dram_resp )
);

// Assignment to the GPIO pads. If dut_gpio_en_o[i] is disabled, then let the gpio_pad[i] float so
// an external device/driver can drive it.
for (genvar i = 0; i < NUM_GPIOS; i++) begin : gen_gpio_pads
assign gpio_pads[i] = dut_gpio_en_o[i] ? dut_gpio_o[i] : 1'bz;
end

// Signals to connect the sink
top_pkg::axi_req_t sim_sram_cpu_req;
top_pkg::axi_resp_t sim_sram_cpu_resp;
Expand Down Expand Up @@ -197,6 +212,7 @@ module tb;
uvm_config_db#(virtual clk_rst_if)::set(null, "*", "sys_clk_if", sys_clk_if);
uvm_config_db#(virtual clk_rst_if)::set(null, "*", "peri_clk_if", peri_clk_if);
uvm_config_db#(virtual uart_if)::set(null, "*.env.m_uart_agent*", "vif", uart_if);
uvm_config_db#(virtual pins_if #(NUM_GPIOS))::set(null, "*.env", "gpio_vif", gpio_if);

// SW logger and test status interfaces.
uvm_config_db#(virtual sw_test_status_if)::set(
Expand Down
2 changes: 2 additions & 0 deletions hw/top_chip/dv/top_chip_sim.core
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ filesets:
- lowrisc:dv:xbar_macros
- lowrisc:dv_dpi_c:uartdpi:0.1
- lowrisc:dv_dpi_sv:uartdpi:0.1
- lowrisc:mocha_dv:gpio_if:0.1
- lowrisc:mocha_dv:gpio_env
files:
- tb/tb.sv
- tb/chip_hier_macros.svh: {is_include_file: true}
Expand Down
8 changes: 7 additions & 1 deletion hw/top_chip/dv/top_chip_sim_cfg.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,16 @@
}
{
name: gpio_smoke
uvm_test_seq: top_chip_dv_gpio_vseq
uvm_test_seq: top_chip_dv_gpio_smoke_vseq
sw_images: ["gpio_smoketest_vanilla_bare:5"]
run_opts: ["+ChipMemSRAM_image_file={run_dir}/gpio_smoketest_vanilla_bare.vmem"]
}
{
name: gpio_smoke_cheri
uvm_test_seq: top_chip_dv_gpio_smoke_vseq
sw_images: ["gpio_smoketest_cheri_bare:5"]
run_opts: ["+ChipMemSRAM_image_file={run_dir}/gpio_smoketest_cheri_bare.vmem"]
}
{
name: rom_ctrl_integrity_check
uvm_test_seq: top_chip_dv_rom_ctrl_integrity_check_vseq
Expand Down
3 changes: 3 additions & 0 deletions sw/device/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ set(LIBS hal runtime startup test_framework)
mocha_add_test(NAME test_framework_test SOURCES test_framework/smoketest.c LIBRARIES ${LIBS} FPGA)
mocha_add_test(NAME test_framework_exception_test SOURCES test_framework/exception.c LIBRARIES ${LIBS})
mocha_add_test(NAME gpio_reg_access_test SOURCES gpio/reg_access_test.c LIBRARIES ${LIBS} FPGA)
# Can't run this test on FPGA's and verilator's tops and this test thinks that the GPIO inputs can
# be driven
mocha_add_test(NAME gpio_smoketest SOURCES gpio/smoketest.c LIBRARIES ${LIBS} SKIP_VERILATOR)
mocha_add_test(NAME i2c_smoketest SOURCES i2c/smoketest.c LIBRARIES ${LIBS} FPGA)
mocha_add_test(NAME mailbox_smoketest SOURCES mailbox/smoketest.c LIBRARIES ${LIBS} FPGA)
mocha_add_test(NAME plic_smoketest SOURCES plic/smoketest.c LIBRARIES ${LIBS} FPGA)
Expand Down
36 changes: 36 additions & 0 deletions sw/device/tests/gpio/smoketest.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright lowRISC contributors (COSMIC project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "hal/gpio.h"
#include "hal/mmio.h"
#include "hal/mocha.h"
#include <stdbool.h>
#include <stdint.h>

static bool gpio_test(gpio_t gpio)
{
// Enable the GPIOs in output mode
DEV_WRITE(gpio + GPIO_REG_DIRECT_OE, 0xFFFFFFFF);

// Set each pin in walking 1's fashion
for (int i = 0; i < GPIO_NUM_PINS; i++) {
DEV_WRITE(gpio + GPIO_REG_DIRECT_OUT, 1 << i);
}

// When the SW is done driving walking 1's on the last GPIO pin, it should disable the
// output enables so that the GPIO pads can safely be driven as inputs.
DEV_WRITE(gpio + GPIO_REG_DIRECT_OE, 0x0);

// Wait for the pads to set high externally
while (DEV_READ(gpio + GPIO_REG_DATA_IN) != 0x55555555) {
}

return true;
}

bool test_main()
{
gpio_t gpio = mocha_system_gpio();
return gpio_test(gpio);
}
Loading