-
Notifications
You must be signed in to change notification settings - Fork 13
[chip, gpio, dv] GPIO smoke test #382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2b54119
9ca99ad
ad02040
25123b0
5408a31
1003ad2
fdbe886
8e92f59
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| // 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) | ||
|
|
||
| // Disable the pull-ups on the pins that was enabled due to support SW booting process | ||
| cfg.gpio_vif.set_pullup_en('0); | ||
|
|
||
| // 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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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; | ||
|
|
@@ -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; | ||
|
|
@@ -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)); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bit confusing that gpio_if is the name of pins_if, maybe gpio_pins_if? |
||
|
|
||
| // ------ Mock DRAM ------ | ||
| top_pkg::axi_dram_req_t dram_req; | ||
|
|
@@ -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 ), | ||
|
|
@@ -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; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just bumped into this when trying to make the bootrom boostrap pin to work with dvsim. Is it possible to make the pin 8 high if output enable high rathen then floating?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess it is possible, can you explain a bit more the reason in order to document this behavior with an explicit comment
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The gpio 8 is now used by the bootrom to decide if it should enter spi bootstrap or jump to the next stage (test). For now we only want to enter spi bootstrap in the FPGA. In sumulation we would load both (rom and test) and skip bootstrap. For that to work we need the gpio 8 to be pulled high during boot.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Kinza showed me the pins_if.sv which already has a pull functionality. Hopefully we can use that and set all the pins to pull up.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @engdoreis, I've done it for every pin in this commit: fdbe886 I can pull out that commit along with 2b54119 in a separate PR if your work is urgent? |
||
| end | ||
|
|
||
| // Signals to connect the sink | ||
| top_pkg::axi_req_t sim_sram_cpu_req; | ||
| top_pkg::axi_resp_t sim_sram_cpu_resp; | ||
|
|
@@ -190,13 +205,19 @@ module tb; | |
| `SIM_SRAM_IF.u_sw_test_status_if.sw_test_status_addr = SW_DV_TEST_STATUS_ADDR; | ||
| `SIM_SRAM_IF.u_sw_logger_if.sw_log_addr = SW_DV_LOG_ADDR; | ||
|
|
||
| // Set the pull ups on GPIO pins. This doesn't mean anything for DV. Rather a feature added for | ||
| // SW. GPIO pin 8 is going to be used by the bootrom to decide the booting process. To support | ||
| // SW booting process in simulation, pin 8 needs to be pulled up during booting. But instead of | ||
| // initializing a single pin as pulled high, we'll do the same for evrey pin. | ||
| gpio_if.set_pullup_en('1); | ||
| // Start clock and reset generators | ||
| sys_clk_if.set_active(); | ||
| peri_clk_if.set_active(); | ||
|
|
||
| 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( | ||
|
|
||
| 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); | ||
| } | ||
|
engdoreis marked this conversation as resolved.
|
||
|
|
||
| // 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); | ||
| } | ||
There was a problem hiding this comment.
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_envas a direct dependency of the sim. Can we drop it from there, maybe?There was a problem hiding this comment.
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 inbuild.logthat it is unable to findtop_chip_dv_env_pkgThere was a problem hiding this comment.
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_GPIOSparameter fromgpio_env_pkgintb.svanduvm. I have an importimport gpio_env_pkg::NUM_GPIOS;intop_chip_dv_env_pkgto be able to use that parameter inUVM. To achieve that I need to have- lowrisc:mocha_dv:gpio_envintop_chip_dv_env.coreThere was a problem hiding this comment.
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:
tb.sv.But I just looked and I don't think
lowrisc:mocha_dv:top_chip_simdepends onlowrisc: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)There was a problem hiding this comment.
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
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @rswarbrick,
I've created a PR for the GPIO dependency issue we discussed yesterday: 29769
This needs to go in first so that I'll vendor the stuff in mocha and then tweak this PR