diff --git a/hw/ip/gpio/data/gpio.hjson b/hw/ip/gpio/data/gpio.hjson index 37f426cb2f72b..deb7cc3fff1c8 100644 --- a/hw/ip/gpio/data/gpio.hjson +++ b/hw/ip/gpio/data/gpio.hjson @@ -111,6 +111,7 @@ package: "", desc: ''' This signal is pulsed high by the power manager after reset in order to sample the HW straps. + It can only be pulsed high one-time after reset. The following pulses will not be taken into consideration. ''', default: "1'b0" }, @@ -390,7 +391,14 @@ ], }, { name: "HW_STRAPS_DATA_IN", - desc: "GPIO Input data sampled as straps during cold boot read value", + desc: ''' + GPIO input data that was sampled as straps as the block came out of reset. + + This register depends on the GpioAsHwStrapsEn parameter. + - If the parameter is false then the register reads as zero. + - If the parameter is true then GPIO input data is sampled on the first cycle after reset + where the strap_en_i input is high. That sampled data is stored in this register. + ''', swaccess: "ro", hwaccess: "hrw", tags: [// Value in the register is determined by GPIO pin values that are sampled diff --git a/hw/ip/gpio/data/gpio_testplan.hjson b/hw/ip/gpio/data/gpio_testplan.hjson index c8588cb3854e6..e09ef17c3ea40 100644 --- a/hw/ip/gpio/data/gpio_testplan.hjson +++ b/hw/ip/gpio/data/gpio_testplan.hjson @@ -145,5 +145,20 @@ stage: V2 tests: ["gpio_stress_all"] } + { + name: straps_data + desc: '''Verify the straps data/valid ouput expected values based on the strap_en and gpio_i inputs: + - Drives gpio_i input with random values. + - Set the strap_en high for at least one clock cycle. + - Read the registers hw_straps_data_in and hw_straps_data_in_valid. + - The data read and sampled_straps_o will be checked in the scoreboard. + - Drive the gpio_o to make sure that has no impact on straps registers. + - Read to make sure that if does not affect the straps registers after drive the gpio_o. + - Apply reset and make sure the strap registers are clean. + - Read straps registers after reset. + - Iterate again the same flow, with new random values.''' + stage: V3 + tests: ["gpio_rand_straps"] + } ] } diff --git a/hw/ip/gpio/doc/registers.md b/hw/ip/gpio/doc/registers.md index cde79bb27e417..cc0734f63dafc 100644 --- a/hw/ip/gpio/doc/registers.md +++ b/hw/ip/gpio/doc/registers.md @@ -359,6 +359,7 @@ Indicates whether the data in [`HW_STRAPS_DATA_IN`](#hw_straps_data_in) is valid ## HW_STRAPS_DATA_IN GPIO Input data sampled as straps during cold boot read value +The GPIO input data is sampled after the first one pulse cycle of straps_en input after reset. - Offset: `0x44` - Reset default: `0x0` - Reset mask: `0xffffffff` diff --git a/hw/ip/gpio/dv/cov/gpio_cov_excl.el b/hw/ip/gpio/dv/cov/gpio_cov_excl.el deleted file mode 100644 index b5ca5b0568b37..0000000000000 --- a/hw/ip/gpio/dv/cov/gpio_cov_excl.el +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -//================================================== -// This file contains the Excluded objects -// Generated By User: gaurangg -// Format Version: 2 -// Date: Wed Oct 30 17:22:12 2019 -// ExclMode: default -//================================================== -CHECKSUM: "3109872245 3727953184" -INSTANCE: tb.dut.u_reg.u_data_in -ANNOTATION: "[UNR]" -Block 1 "0" "assign wr_en = de;" -CHECKSUM: "1352181506 3803838024" -INSTANCE: tb.dut.u_reg.u_masked_out_lower_mask -ANNOTATION: "[UNR]" -Block 1 "0" "assign qs = d;" -CHECKSUM: "1352181506 3803838024" -INSTANCE: tb.dut.u_reg.u_masked_out_upper_mask -ANNOTATION: "[UNR]" -Block 1 "0" "assign qs = d;" -CHECKSUM: "1352181506 3803838024" -INSTANCE: tb.dut.u_reg.u_masked_oe_lower_mask -ANNOTATION: "[UNR]" -Block 1 "0" "assign qs = d;" -CHECKSUM: "1352181506 3803838024" -INSTANCE: tb.dut.u_reg.u_masked_oe_upper_mask -ANNOTATION: "[UNR]" -Block 1 "0" "assign qs = d;" -CHECKSUM: "3109872245 1595801502" -INSTANCE: tb.dut.u_reg.u_data_in -ANNOTATION: "[UNR]" -Branch 1 "1017474648" "(!rst_ni)" (2) "(!rst_ni) 0,0" diff --git a/hw/ip/gpio/dv/env/gpio_env.core b/hw/ip/gpio/dv/env/gpio_env.core index da4d4389683e1..7e4c39ede5441 100644 --- a/hw/ip/gpio/dv/env/gpio_env.core +++ b/hw/ip/gpio/dv/env/gpio_env.core @@ -28,6 +28,7 @@ filesets: - seq_lib/gpio_stress_all_vseq.sv: {is_include_file: true} - seq_lib/gpio_intr_rand_pgm_vseq.sv: {is_include_file: true} - seq_lib/gpio_intr_with_filter_rand_intr_event_vseq.sv: {is_include_file: true} + - seq_lib/gpio_rand_straps_vseq.sv : {is_include_file: true} file_type: systemVerilogSource generate: diff --git a/hw/ip/gpio/dv/env/gpio_env.sv b/hw/ip/gpio/dv/env/gpio_env.sv index 111ac6c7a7e16..ced2992614c1a 100644 --- a/hw/ip/gpio/dv/env/gpio_env.sv +++ b/hw/ip/gpio/dv/env/gpio_env.sv @@ -17,6 +17,9 @@ class gpio_env extends cip_base_env #( if (!uvm_config_db#(gpio_vif)::get(this, "", "gpio_vif", cfg.gpio_vif)) begin `uvm_fatal(get_full_name(), "failed to get gpio_vif from uvm_config_db") end + if (!uvm_config_db#(straps_vif)::get(this, "", "straps_vif", cfg.straps_vif_inst)) begin + `uvm_fatal(get_full_name(), "Virtual interface straps_vif_inst is not set") + end endfunction endclass diff --git a/hw/ip/gpio/dv/env/gpio_env_cfg.sv b/hw/ip/gpio/dv/env/gpio_env_cfg.sv index c8af480a21b31..e9e269c8d4cbe 100644 --- a/hw/ip/gpio/dv/env/gpio_env_cfg.sv +++ b/hw/ip/gpio/dv/env/gpio_env_cfg.sv @@ -13,11 +13,16 @@ class gpio_env_cfg extends cip_base_env_cfg #( rand bit pulldown_en; // gpio virtual interface gpio_vif gpio_vif; + // gpio straps interface + straps_vif straps_vif_inst; constraint pullup_pulldown_en_c {pullup_en ^ pulldown_en;} `uvm_object_utils(gpio_env_cfg) - `uvm_object_new + + function new(string name = "gpio_env_cfg"); + super.new(name); + endfunction virtual function void initialize(bit [TL_AW-1:0] csr_base_addr = '1); list_of_alerts = gpio_env_pkg::LIST_OF_ALERTS; @@ -27,6 +32,9 @@ class gpio_env_cfg extends cip_base_env_cfg #( // only support 1 outstanding TL item m_tl_agent_cfg.max_outstanding_req = 1; + + // Used to allow reset operation during a stress all tests and check the CSR after that. + can_reset_with_csr_accesses = 1'b1; endfunction : initialize endclass diff --git a/hw/ip/gpio/dv/env/gpio_env_pkg.sv b/hw/ip/gpio/dv/env/gpio_env_pkg.sv index 1c94585f24835..d6d8ecb371fd2 100644 --- a/hw/ip/gpio/dv/env/gpio_env_pkg.sv +++ b/hw/ip/gpio/dv/env/gpio_env_pkg.sv @@ -27,6 +27,7 @@ package gpio_env_pkg; parameter string LIST_OF_ALERTS[] = {"fatal_fault"}; typedef virtual pins_if #(NUM_GPIOS) gpio_vif; + typedef virtual gpio_straps_if straps_vif; typedef class gpio_env_cfg; typedef class gpio_env_cov; typedef cip_base_virtual_sequencer #(gpio_env_cfg, gpio_env_cov) gpio_virtual_sequencer; diff --git a/hw/ip/gpio/dv/env/gpio_scoreboard.sv b/hw/ip/gpio/dv/env/gpio_scoreboard.sv index 26f53a7abbe94..bb75880574d3c 100644 --- a/hw/ip/gpio/dv/env/gpio_scoreboard.sv +++ b/hw/ip/gpio/dv/env/gpio_scoreboard.sv @@ -31,6 +31,8 @@ class gpio_scoreboard extends cip_base_scoreboard #(.CFG_T (gpio_env_cfg), // (i) indicate that write to INTR_STATE register just happened, and // (ii) store information of which all interupt bits were cleared bit [TL_DW-1:0] cleared_intr_bits; + // Flag to indicate that the strap was trigered + bit first_strap_trigged; // mask are WO, store the values in scb uvm_reg_data_t masked_out_lower_mask; @@ -40,7 +42,9 @@ class gpio_scoreboard extends cip_base_scoreboard #(.CFG_T (gpio_env_cfg), `uvm_component_utils(gpio_scoreboard) - `uvm_component_new + function new (string name = "gpio_scoreboard", uvm_component parent = null); + super.new (name, parent); + endfunction // Function: build_phase function void build_phase(uvm_phase phase); @@ -54,6 +58,8 @@ class gpio_scoreboard extends cip_base_scoreboard #(.CFG_T (gpio_env_cfg), fork monitor_gpio_i(); monitor_gpio_interrupt_pins(); + monitor_gpio_straps(); + handle_reset(); join_none endtask @@ -360,6 +366,48 @@ class gpio_scoreboard extends cip_base_scoreboard #(.CFG_T (gpio_env_cfg), end endtask : monitor_gpio_interrupt_pins + // Task: monitor_gpio_straps + virtual task monitor_gpio_straps(); + forever begin : monitor_gpio_intr + @(posedge cfg.clk_rst_vif.clk) + if(!cfg.under_reset) begin + if (|gpio_i_driven === 1'b1) begin + @(negedge cfg.straps_vif_inst.strap_en) begin + if (first_strap_trigged == 0) begin + // Update data_in ral register value based on result of input + void'(ral.hw_straps_data_in.predict(.value(gpio_i_driven), .kind(UVM_PREDICT_DIRECT))); + // Update data_in valid register value based on result of input + void'(ral.hw_straps_data_in_valid.predict(.value('b1), .kind(UVM_PREDICT_DIRECT))); + check_straps(); + end + end + end + end + end + endtask : monitor_gpio_straps + + virtual protected task handle_reset(); + forever begin + @(negedge cfg.clk_rst_vif.rst_n); + cfg.under_reset = 1; + @(posedge cfg.clk_rst_vif.rst_n); + cfg.under_reset = 0; + end + endtask + + // Function: check_straps + // Used to check the behavior of the straps register data. + // Based on strap_en input value, the straps register data should contains the snapshot of the data_in pins + function void check_straps(); + // Checker: Compare actual values of gpio pins with straps register. + // Check the register hw_straps_data_in against gpio_i pins + `DV_CHECK_CASE_EQ(gpio_i_driven, cfg.straps_vif_inst.sampled_straps.data) + // Check the register hw_straps_data_in_valid + `DV_CHECK_CASE_EQ('b1, cfg.straps_vif_inst.sampled_straps.valid) + // Turn-off the checker after the first strap trigger. + first_strap_trigged = 1; + endfunction : check_straps + // Function: actual_gpio_i_activity function bit actual_gpio_i_activity(); return ~((prv_gpio_i_pins_o === cfg.gpio_vif.pins_o) && @@ -561,6 +609,7 @@ class gpio_scoreboard extends cip_base_scoreboard #(.CFG_T (gpio_env_cfg), ((|gpio_i_driven === 1'b1) && (actual_gpio_i_activity() == 1))) begin `DV_CHECK_CASE_EQ(pred_val_gpio_pins, cfg.gpio_vif.pins) end + end endfunction : gpio_predict_and_compare @@ -804,6 +853,7 @@ class gpio_scoreboard extends cip_base_scoreboard #(.CFG_T (gpio_env_cfg), last_intr_update_except_clearing = '0; last_intr_test_event = '0; cleared_intr_bits = '0; + first_strap_trigged = 0; endfunction // Function: check_phase diff --git a/hw/ip/gpio/dv/env/seq_lib/gpio_rand_straps_vseq.sv b/hw/ip/gpio/dv/env/seq_lib/gpio_rand_straps_vseq.sv new file mode 100644 index 0000000000000..b3336f9af5f18 --- /dev/null +++ b/hw/ip/gpio/dv/env/seq_lib/gpio_rand_straps_vseq.sv @@ -0,0 +1,134 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// class : gpio_rand_straps_vseq +// This gpio random test sequence performs following in each of multiple iterations: +// - Drives gpio_i input with random values +// - Set the expected strap_data_in based on the condition if is the first triggered strap_en or not +// - Updates the RAL model with the expected strap_data_in and strap_data_in_valid +// - Trigger the strap_en with one clock cycles +// - Read the registers hw_straps_data_in and hw_straps_data_in_valid +// - Check the expected behavior in the scoreboard and also on csr checks +class gpio_rand_straps_vseq extends gpio_base_vseq; + + `uvm_object_utils(gpio_rand_straps_vseq) + + // gpio input to drive + rand bit [NUM_GPIOS-1:0] gpio_i; + // gpio output to program in register + rand bit [NUM_GPIOS-1:0] gpio_o; + // gpio output enable to program in register + rand bit [NUM_GPIOS-1:0] gpio_oe; + // Flag to indicate that the first trigger straps happened + bit straps_triggered; + // Read straps_data_in + bit [NUM_GPIOS-1:0] rd_hw_straps_data_in; + // Read straps_data_in valid + bit rd_hw_straps_data_in_valid; + // Expected strap data_in + bit [NUM_GPIOS-1:0] exp_strap_data_in; + + constraint num_trans_c { + num_trans inside {[20:200]}; + } + + function new(string name = "gpio_rand_straps_vseq"); + super.new(name); + endfunction + + task body(); + `uvm_info(`gfn, $sformatf("num_trans = %0d", num_trans), UVM_HIGH) + + for (uint tr_num = 0; tr_num < num_trans; tr_num++) begin + string msg_id = {`gfn, $sformatf(" Transaction-%0d", tr_num)}; + `DV_CHECK_MEMBER_RANDOMIZE_FATAL(delay) + `DV_CHECK_MEMBER_RANDOMIZE_FATAL(gpio_i) + `DV_CHECK_MEMBER_RANDOMIZE_FATAL(gpio_o) + `DV_CHECK_MEMBER_RANDOMIZE_FATAL(gpio_oe) + + cfg.clk_rst_vif.wait_clks(delay); + `uvm_info(msg_id, $sformatf("delay = %0d", delay), UVM_HIGH) + // Step-1 Drive the gpio_i + drive_gpio_in(gpio_i); + + // Wait at least one clock cycle + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(delay, delay >= 1;) + cfg.clk_rst_vif.wait_clks(delay); + + // Step-2 Trigger the snapshot of gpio_i to be stored in the straps registers + cfg.straps_vif_inst.gpio_strap_en = 1; + cfg.clk_rst_vif.wait_clks(1); + cfg.straps_vif_inst.gpio_strap_en = 0; + + // Step-3 Read the HW_STRAPS_DATA_IN register + // Reading straps data_in will trigger a check inside scoreboard + + // Wait at least one clock cycle + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(delay, delay >= 1;) + cfg.clk_rst_vif.wait_clks(delay); + + // Step-4 Read the hw_straps_data_in and check the expected value in the scoreboard + csr_rd(.ptr(ral.hw_straps_data_in), .value(rd_hw_straps_data_in)); + // Read the hw_straps_data_in_valid and check the expected value in the scoreboard + csr_rd(.ptr(ral.hw_straps_data_in_valid), .value(rd_hw_straps_data_in_valid)); + + // Wait at least one clock cycle + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(delay, delay >= 1;) + cfg.clk_rst_vif.wait_clks(delay); + + // Stop driving gpio_i + undrive_gpio_in(); + + // Wait at least one clock cycle + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(delay, delay >= 1;) + cfg.clk_rst_vif.wait_clks(delay); + + // Step-5 Read to make sure that if does not affect the straps registers after undrive the gpio_in + csr_rd(.ptr(ral.hw_straps_data_in), .value(rd_hw_straps_data_in)); + csr_rd(.ptr(ral.hw_straps_data_in_valid), .value(rd_hw_straps_data_in_valid)); + + // Wait at least one clock cycle + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(delay, delay >= 1;) + cfg.clk_rst_vif.wait_clks(delay); + + // Additional verification + // Drive the gpio_o to make sure that has no impact on straps registers. + // test gpio outputs + cfg.gpio_vif.drive_en('0); + + ral.direct_out.set(gpio_o); + ral.direct_oe.set(gpio_oe); + csr_update(.csr(ral.direct_out)); + csr_update(.csr(ral.direct_oe)); + + // Wait at least one clock cycle + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(delay, delay >= 1;) + cfg.clk_rst_vif.wait_clks(delay); + + // Step-7 Read to make sure that if does not affect the straps registers after drive the gpio_o + csr_rd(.ptr(ral.hw_straps_data_in), .value(rd_hw_straps_data_in)); + csr_rd(.ptr(ral.hw_straps_data_in_valid), .value(rd_hw_straps_data_in_valid)); + + // Wait at least one clock cycle + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(delay, delay >= 1;) + cfg.clk_rst_vif.wait_clks(delay); + + // Apply reset and make sure the strap registers are clean + apply_reset(); + + // Wait at least one clock cycle + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(delay, delay >= 1;) + cfg.clk_rst_vif.wait_clks(delay); + + // Step-8 Read the straps registers after reset + csr_rd(.ptr(ral.hw_straps_data_in), .value(rd_hw_straps_data_in)); + csr_rd(.ptr(ral.hw_straps_data_in_valid), .value(rd_hw_straps_data_in_valid)); + + `uvm_info(msg_id, "End of Transaction", UVM_HIGH) + + end // end for + + endtask : body + +endclass : gpio_rand_straps_vseq diff --git a/hw/ip/gpio/dv/env/seq_lib/gpio_vseq_list.sv b/hw/ip/gpio/dv/env/seq_lib/gpio_vseq_list.sv index fd508cad328b8..ab7a840ca9d85 100644 --- a/hw/ip/gpio/dv/env/seq_lib/gpio_vseq_list.sv +++ b/hw/ip/gpio/dv/env/seq_lib/gpio_vseq_list.sv @@ -14,3 +14,4 @@ `include "gpio_random_long_reg_writes_reg_reads_vseq.sv" `include "gpio_full_random_vseq.sv" `include "gpio_stress_all_vseq.sv" +`include "gpio_rand_straps_vseq.sv" diff --git a/hw/ip/gpio/dv/gpio_sim.core b/hw/ip/gpio/dv/gpio_sim.core index a33d0dc74f66e..325079ca43de6 100644 --- a/hw/ip/gpio/dv/gpio_sim.core +++ b/hw/ip/gpio/dv/gpio_sim.core @@ -13,6 +13,7 @@ filesets: depend: - lowrisc:dv:gpio_test - lowrisc:dv:gpio_sva + - lowrisc:dv:gpio_if files: - tb/tb.sv file_type: systemVerilogSource diff --git a/hw/ip/gpio/dv/gpio_sim_cfg.hjson b/hw/ip/gpio/dv/gpio_sim_cfg.hjson index 6a8910a766954..0c8405987837e 100644 --- a/hw/ip/gpio/dv/gpio_sim_cfg.hjson +++ b/hw/ip/gpio/dv/gpio_sim_cfg.hjson @@ -180,6 +180,10 @@ build_mode: en_cdc_prims run_opts: ["+no_pullup_pulldown=1"] } + { + name: gpio_rand_straps + uvm_test_seq: gpio_rand_straps_vseq + } ] // List of regressions. diff --git a/hw/ip/gpio/dv/interfaces/gpio_if.core b/hw/ip/gpio/dv/interfaces/gpio_if.core new file mode 100644 index 0000000000000..c3d4a82ce3654 --- /dev/null +++ b/hw/ip/gpio/dv/interfaces/gpio_if.core @@ -0,0 +1,18 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: "lowrisc:dv:gpio_if:0.1" +description: "GPIO Interfaces" +filesets: + files_dv: + depend: + - lowrisc:ip:gpio:0.1 + files: + - gpio_straps_if.sv + file_type: systemVerilogSource + +targets: + default: + filesets: + - files_dv diff --git a/hw/ip/gpio/dv/interfaces/gpio_straps_if.sv b/hw/ip/gpio/dv/interfaces/gpio_straps_if.sv new file mode 100644 index 0000000000000..b627be02de301 --- /dev/null +++ b/hw/ip/gpio/dv/interfaces/gpio_straps_if.sv @@ -0,0 +1,21 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// interface : gpio_straps_if +`ifndef GPIO_STRAPS_IF_SV +`define GPIO_STRAPS_IF_SV + +import gpio_pkg::*; + +// Interface definition +interface gpio_straps_if ( + inout strap_en, // Signal to enable straps + input gpio_straps_t sampled_straps // Sampled gpio_i snapshot data from GPIO (DUT) +); + + logic gpio_strap_en; + assign strap_en = gpio_strap_en; + +endinterface + +`endif // GPIO_STRAPS_IF_SV diff --git a/hw/ip/gpio/dv/tb/tb.sv b/hw/ip/gpio/dv/tb/tb.sv index 94e8ebac0b7c0..492bea67dd286 100644 --- a/hw/ip/gpio/dv/tb/tb.sv +++ b/hw/ip/gpio/dv/tb/tb.sv @@ -11,8 +11,6 @@ module tb; import gpio_env_pkg::*; import gpio_test_pkg::*; import gpio_reg_pkg::*; - import gpio_pkg::*; - // macro includes `include "uvm_macros.svh" `include "dv_macros.svh" @@ -24,6 +22,8 @@ module tb; wire [NUM_GPIOS-1:0] gpio_oe; wire [NUM_GPIOS-1:0] gpio_intr; wire [NUM_MAX_INTERRUPTS-1:0] interrupts; + gpio_straps_t sampled_straps; + wire strap_en; `DV_ALERT_IF_CONNECT() @@ -33,6 +33,8 @@ module tb; .rst_n(rst_n) ); pins_if #(NUM_MAX_INTERRUPTS) intr_if (.pins(interrupts)); + gpio_straps_if straps_if_inst (.strap_en(strap_en), + .sampled_straps(sampled_straps)); tl_if tl_if ( .clk (clk), .rst_n(rst_n) @@ -52,9 +54,8 @@ module tb; .clk_i (clk), .rst_ni(rst_n), - // TODO: need to test snapshot functionality - .strap_en_i(1'b0), - .sampled_straps_o(), + .strap_en_i(strap_en), + .sampled_straps_o(sampled_straps), .tl_i(tl_if.h2d), .tl_o(tl_if.d2h), @@ -85,6 +86,7 @@ module tb; uvm_config_db#(intr_vif)::set(null, "*.env", "intr_vif", intr_if); uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent*", "vif", tl_if); uvm_config_db#(virtual pins_if #(NUM_GPIOS))::set(null, "*.env", "gpio_vif", gpio_if); + uvm_config_db#(virtual gpio_straps_if)::set(null, "*.*", "straps_vif", straps_if_inst); $timeformat(-12, 0, " ps", 12); run_test(); end diff --git a/hw/ip/gpio/dv/tests/gpio_base_test.sv b/hw/ip/gpio/dv/tests/gpio_base_test.sv index e12c37d4c78ee..0c8f30aef6b51 100644 --- a/hw/ip/gpio/dv/tests/gpio_base_test.sv +++ b/hw/ip/gpio/dv/tests/gpio_base_test.sv @@ -7,10 +7,22 @@ class gpio_base_test extends cip_base_test #( .CFG_T(gpio_env_cfg) ); `uvm_component_utils(gpio_base_test) - `uvm_component_new + straps_vif straps_vif_inst; // Virtual interface + function new(string name, uvm_component parent); + super.new(name, parent); + endfunction + task reset_phase(uvm_phase phase); + phase.raise_objection(this); + // Initialize inputs + straps_vif_inst.gpio_strap_en = 0; + phase.drop_objection(this); + endtask virtual function void build_phase(uvm_phase phase); super.build_phase(phase); + if (!uvm_config_db#(straps_vif)::get(this, "*.*", "straps_vif", straps_vif_inst)) begin + `uvm_fatal("SEQ", "Virtual interface straps_vif_inst is not set") + end endfunction : build_phase endclass : gpio_base_test