From 4aa111a36d2286eda42d473cad49edd8706b0bd7 Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Thu, 25 Jul 2024 21:35:33 +0100 Subject: [PATCH] [rv_dm,dv] Expand the implementation of mem_tl_access_resuming This expands the code a bit to make it clearer what's going on. It also drops the loop: that doesn't seem to make all that much sense (and nor does a randomised resume request). Honestly, this is really a cut-down version of rv_dm_halt_resume_whereto_vseq. That sequence tries to request an abstract command and then checks the whereto register contains the start of that command. It probably makes sense to keep this (more simple) test as well, partly because the code is dramatically easier to understand. Signed-off-by: Rupert Swarbrick --- .../rv_dm_mem_tl_access_resuming_vseq.sv | 85 +++++++++++++------ 1 file changed, 58 insertions(+), 27 deletions(-) diff --git a/hw/ip/rv_dm/dv/env/seq_lib/rv_dm_mem_tl_access_resuming_vseq.sv b/hw/ip/rv_dm/dv/env/seq_lib/rv_dm_mem_tl_access_resuming_vseq.sv index cbc4f4111521d..52cd9eb9bb395 100644 --- a/hw/ip/rv_dm/dv/env/seq_lib/rv_dm_mem_tl_access_resuming_vseq.sv +++ b/hw/ip/rv_dm/dv/env/seq_lib/rv_dm_mem_tl_access_resuming_vseq.sv @@ -2,38 +2,69 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 -// RESUMING test vseq class rv_dm_mem_tl_access_resuming_vseq extends rv_dm_base_vseq; `uvm_object_utils(rv_dm_mem_tl_access_resuming_vseq) `uvm_object_new + task mirror_dmstatus(); + uvm_status_e dmi_status; + jtag_dmi_ral.dmstatus.mirror(.status(dmi_status), .check(UVM_NO_CHECK)); + `DV_CHECK_EQ(dmi_status, UVM_IS_OK) + endtask + + // Write to the resumereq field in dmcontrol to ask the (only) hart to resume. Check that the + // resume request is reflected in RESUME (bit 1) of the FLAGS register. Then respond as the hart + // to acknowledge the request. + task request_resume(); + uvm_status_e reg_status; + uvm_reg_data_t mirrored_flags; + + jtag_dmi_ral.dmcontrol.resumereq.set(1'b1); + jtag_dmi_ral.dmcontrol.update(.status(reg_status)); + `DV_CHECK_EQ(reg_status, UVM_IS_OK) + + // Make sure that the FLAGS register reflects the resume request that we just made, because the + // RESUME bit (at index 1) should be set. + tl_mem_ral.flags[0].mirror(.status(reg_status), .check(UVM_NO_CHECK)); + `DV_CHECK_EQ(reg_status, UVM_IS_OK) + mirrored_flags = `gmv(tl_mem_ral.flags[0]); + `DV_CHECK_EQ(mirrored_flags[1], 1'b1) + + // As the hart, we should respond to the resume request by writing the hart id the RESUMING flag + tl_mem_ral.resuming.write(.status(reg_status), .value(0)); + `DV_CHECK_EQ(reg_status, UVM_IS_OK) + endtask + task body(); - uvm_reg_data_t wdata; - uvm_reg_data_t rdata; + uvm_status_e dmi_status; + // Disable unavailable signal to make sure that hart should be in known // state. If hart is unavailable then it could not halted. cfg.rv_dm_vif.unavailable <= 0; - repeat ($urandom_range(1, 10)) begin - wdata = $urandom_range(0,1); - // Verify that writing to RESUMING results in anyresumeack and - // allresumeack to be set.When resumereq bit is set, - // it will clear the anyresumeack and allresumeack. - request_halt(); - csr_rd(.ptr(jtag_dmi_ral.dmstatus), .value(rdata)); - `DV_CHECK_EQ(1, get_field_val(jtag_dmi_ral.dmstatus.anyhalted, rdata)) - `DV_CHECK_EQ(1, get_field_val(jtag_dmi_ral.dmstatus.allhalted, rdata)) - cfg.clk_rst_vif.wait_clks($urandom_range(0, 1000)); - csr_wr(.ptr(jtag_dmi_ral.dmcontrol.haltreq), .value(0)); - csr_wr(.ptr(tl_mem_ral.resuming), .value(0)); - cfg.clk_rst_vif.wait_clks($urandom_range(0, 1000)); - csr_wr(.ptr(jtag_dmi_ral.dmcontrol.resumereq), .value(wdata)); - csr_rd(.ptr(jtag_dmi_ral.dmstatus), .value(rdata)); - `DV_CHECK_EQ(!wdata, get_field_val(jtag_dmi_ral.dmstatus.anyresumeack, rdata)) - `DV_CHECK_EQ(!wdata, get_field_val(jtag_dmi_ral.dmstatus.allresumeack, rdata)) - `DV_CHECK_EQ(1, get_field_val(jtag_dmi_ral.dmstatus.anyrunning, rdata)) - `DV_CHECK_EQ(1, get_field_val(jtag_dmi_ral.dmstatus.allrunning, rdata)) - cfg.clk_rst_vif.wait_clks($urandom_range(1, 10)); - end - endtask : body - -endclass : rv_dm_mem_tl_access_resuming_vseq + + // Request a halt as the debugger and then acknowledge it as the hart. + request_halt(); + + // At this point, dmstatus should reflect the fact that the one and only hart has halted. Read + // it back and check this is true. + mirror_dmstatus(); + `DV_CHECK_EQ(`gmv(jtag_dmi_ral.dmstatus.anyhalted), 1'b1) + `DV_CHECK_EQ(`gmv(jtag_dmi_ral.dmstatus.allhalted), 1'b1) + + // Clear the halt request + jtag_dmi_ral.dmcontrol.haltreq.set(1'b0); + jtag_dmi_ral.dmcontrol.update(.status(dmi_status)); + `DV_CHECK_EQ(dmi_status, UVM_IS_OK) + + // Now tell the hart to resume, and acknowledge the request as the hart. + request_resume(); + + // At this point, reading dmstatus from debug module should show that the one and only hart has + // acknowledged the resume request. It should also show that the hart is running. + mirror_dmstatus(); + `DV_CHECK_EQ(`gmv(jtag_dmi_ral.dmstatus.anyresumeack), 1'b1) + `DV_CHECK_EQ(`gmv(jtag_dmi_ral.dmstatus.allresumeack), 1'b1) + `DV_CHECK_EQ(`gmv(jtag_dmi_ral.dmstatus.anyrunning), 1'b1) + `DV_CHECK_EQ(`gmv(jtag_dmi_ral.dmstatus.allrunning), 1'b1) + endtask +endclass