blob: a457aa9a34c282cf2e2397e7739f081ae7566495 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
class jtag_riscv_monitor extends dv_base_monitor #(
.ITEM_T(jtag_riscv_item),
.CFG_T (jtag_riscv_agent_cfg),
.COV_T (jtag_riscv_agent_cov)
);
`uvm_component_utils(jtag_riscv_monitor)
uvm_tlm_analysis_fifo #(jtag_item) jtag_item_fifo;
`uvm_component_new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
jtag_item_fifo = new("jtag_item_fifo", this);
endfunction
// collect transactions
virtual protected task collect_trans(uvm_phase phase);
jtag_item item;
logic [DMI_OPW-1:0] op_raw;
jtag_op_e op;
logic [DMI_ADDRW-1:0] addr;
logic [DMI_DATAW-1:0] data;
// Saved op field from initial transaction
jtag_op_e saved_op;
bit dmi_selected;
ITEM_T monitor_item;
forever begin
jtag_item_fifo.get(item);
`uvm_info(`gfn, item.sprint(uvm_default_line_printer), UVM_HIGH)
if (item.ir_len) begin
// Instruction register transaction
if (item.ir == JtagDmiAccess) dmi_selected = 1;
else dmi_selected = 0;
end else if (dmi_selected && cfg.is_rv_dm) begin
// (b/302151393) Run the checks when rv_dm is active
// DR transaction and DMI selected by the instruction register.
// Extract op from the transaction data register.
op_raw = item.dr[DMI_OPW-1 : 0];
op = jtag_op_e'(op_raw);
if (op_raw === DmiRead || op_raw === DmiWrite) begin
// Read / write request
addr = item.dr[DMI_ADDRW+DMI_DATAW+DMI_OPW-1 : DMI_DATAW+DMI_OPW];
data = item.dr[DMI_DATAW+DMI_OPW-1 : DMI_OPW];
`uvm_info(`gfn, $sformatf(
"Got request - op:%0s addr:0x%0h data:0x%0h", op.name, addr, data), UVM_HIGH)
// Save 'op' field to use when a successful status transaction arrives below
saved_op = op;
end else if (op_raw === DmiStatus) begin
logic [DMI_OPW-1:0] status_raw;
jtag_op_status_e status;
// Status / response DR transaction
// Extract status fields
status_raw = item.dout[DMI_OPW-1 : 0];
status = jtag_op_status_e'(status_raw);
addr = item.dout[DMI_ADDRW+DMI_DATAW+DMI_OPW-1 : DMI_DATAW+DMI_OPW];
data = item.dout[DMI_DATAW+DMI_OPW-1 : DMI_OPW];
// Only monitor packets for completed transactions -
// Not retries (status===DmiInProgress)
if (status_raw === DmiNoErr || status_raw === DmiFail) begin
`uvm_create_obj(ITEM_T, monitor_item)
monitor_item.addr = addr;
monitor_item.op = saved_op;
monitor_item.data = data;
monitor_item.status = status;
analysis_port.write(monitor_item);
`uvm_info(`gfn, monitor_item.sprint(uvm_default_line_printer), UVM_MEDIUM)
end else if (status_raw === DmiInProgress) begin
`uvm_info(`gfn, $sformatf(
"Got busy status %0s - op:%0s addr:0x%0h", status.name, op.name, addr),
UVM_HIGH)
end else begin
string msg = $sformatf("Bad status - %0s(0x%0h) ", status.name, status_raw);
if (!cfg.allow_errors) begin
`uvm_error(`gfn, msg)
end else begin
`uvm_info(`gfn, msg, UVM_HIGH)
end
end
end else begin
`uvm_error(`gfn, $sformatf("Bad op - %0s(0x%0h)", op.name, op_raw))
end
end
end
endtask
endclass