Skip to content
Open
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
30 changes: 30 additions & 0 deletions hw/dv/vip/axi4_vip/axi4_vip.core
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
CAPI=2:
# Copyright lowRISC contributors (COSMIC project).
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

name : lowrisc:dv:axi4_vip:0.1

filesets:
files_dv:
depend:
- lowrisc:dv:dv_macros
files:
- axi4_vip_if.sv
- axi4_vip_pkg.sv
- axi4_vip_defines.svh: {is_include_file: true}
- axi4_vip_types.svh: {is_include_file: true}
- axi4_vip_env_cfg.svh: {is_include_file: true}
- axi4_vip_item.svh: {is_include_file: true}
- axi4_vip_driver.svh: {is_include_file: true}
- axi4_vip_sequencer.svh: {is_include_file: true}
- axi4_vip_monitor.svh: {is_include_file: true}
- axi4_vip_manager_agent.svh: {is_include_file: true}
- axi4_vip_subordinate_agent.svh: {is_include_file: true}
- axi4_vip_env.svh: {is_include_file: true}
file_type: systemVerilogSource

targets:
default:
filesets:
- files_dv
11 changes: 11 additions & 0 deletions hw/dv/vip/axi4_vip/axi4_vip_defines.svh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright lowRISC contributors (COSMIC project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

// maximum supported bus widths
`define AXI4_MAX_ID_WIDTH 16
`define AXI4_MAX_ADDR_WIDTH 64
`define AXI4_MAX_DATA_WIDTH 1024
`define AXI4_MAX_USER_WIDTH 32
`define AXI4_MAX_REGION_WIDTH 8
`define AXI4_MAX_QOS_WIDTH 8
30 changes: 30 additions & 0 deletions hw/dv/vip/axi4_vip/axi4_vip_driver.svh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright lowRISC contributors (COSMIC project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

class axi4_vip_driver extends uvm_driver #(axi4_vip_item);

`uvm_component_utils(axi4_vip_driver)

axi4_vip_env_cfg m_cfg;
virtual axi4_vip_if vif;

extern function new(string name, uvm_component parent);
extern function void build_phase(uvm_phase phase);

endclass : axi4_vip_driver

function axi4_vip_driver::new(string name, uvm_component parent);
super.new(name, parent);
endfunction : new

function void axi4_vip_driver::build_phase(uvm_phase phase);
super.build_phase(phase);
if (!uvm_config_db#(axi4_vip_env_cfg)::get(this, "", "m_cfg", m_cfg)) begin
`uvm_fatal("NOCFG", {"Configuration item must be set for: ", get_full_name(), ".m_cfg"})
end

if (!uvm_config_db#(virtual axi4_vip_if)::get(this, "", "vif", vif)) begin
`uvm_fatal("NOVIF", {"virtual interface must be set for: ", get_full_name(), ".vif"})
end
endfunction : build_phase
43 changes: 43 additions & 0 deletions hw/dv/vip/axi4_vip/axi4_vip_env.svh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright lowRISC contributors (COSMIC project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

class axi4_vip_env extends uvm_env;

`uvm_component_utils(axi4_vip_env)

axi4_vip_env_cfg m_cfg;

// Created when the env is configured to monitor the manager side of an AXI link.
axi4_vip_manager_agent m_manager;
// Created when the env is configured to monitor the subordinate side of an AXI link.
axi4_vip_subordinate_agent m_subordinate;
Comment on lines +12 to +14
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Documentation comments would be nice for these two variables.


extern function new(string name, uvm_component parent);
extern function void build_phase(uvm_phase phase);

endclass : axi4_vip_env

function axi4_vip_env::new(string name, uvm_component parent);
super.new(name, parent);
endfunction : new

function void axi4_vip_env::build_phase(uvm_phase phase);
super.build_phase(phase);

if (!uvm_config_db#(axi4_vip_env_cfg)::get(this, "", "m_cfg", m_cfg)) begin
`uvm_fatal("NOCFG", {"Configuration item must be set for: ", get_full_name(), ".m_cfg"})
end

if (!m_cfg.m_has_manager && !m_cfg.m_has_subordinate) begin
`uvm_fatal("BADCFG", "An AXI VIP instance must monitor at least one side")
end

if (m_cfg.m_has_manager) begin
m_manager = axi4_vip_manager_agent::type_id::create("m_manager", this);
end

if (m_cfg.m_has_subordinate) begin
m_subordinate = axi4_vip_subordinate_agent::type_id::create("m_subordinate", this);
end
endfunction : build_phase
104 changes: 104 additions & 0 deletions hw/dv/vip/axi4_vip/axi4_vip_env_cfg.svh
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright lowRISC contributors (COSMIC project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

class axi4_vip_env_cfg extends uvm_object;

string m_inst_id = "AXI4";
bit m_has_manager = 0;
uvm_active_passive_enum m_manager_active_passive = UVM_PASSIVE;
bit m_has_subordinate = 0;
uvm_active_passive_enum m_subordinate_active_passive = UVM_PASSIVE;

int unsigned m_id_width = `AXI4_MAX_ID_WIDTH;
int unsigned m_addr_width = `AXI4_MAX_ADDR_WIDTH;
int unsigned m_data_width = `AXI4_MAX_DATA_WIDTH;
int unsigned m_user_width = `AXI4_MAX_USER_WIDTH;
int unsigned m_region_width = `AXI4_MAX_REGION_WIDTH;
int unsigned m_qos_width = `AXI4_MAX_QOS_WIDTH;

`uvm_object_utils_begin(axi4_vip_env_cfg)
`uvm_field_string(m_inst_id, UVM_DEFAULT | UVM_STRING)
`uvm_field_int(m_has_manager, UVM_DEFAULT)
`uvm_field_int(m_has_subordinate, UVM_DEFAULT)
`uvm_field_enum(uvm_active_passive_enum, m_manager_active_passive, UVM_DEFAULT)
`uvm_field_enum(uvm_active_passive_enum, m_subordinate_active_passive, UVM_DEFAULT)
`uvm_field_int(m_id_width, UVM_DEFAULT)
`uvm_field_int(m_addr_width, UVM_DEFAULT)
`uvm_field_int(m_data_width, UVM_DEFAULT)
`uvm_field_int(m_user_width, UVM_DEFAULT)
`uvm_field_int(m_region_width, UVM_DEFAULT)
`uvm_field_int(m_qos_width, UVM_DEFAULT)
`uvm_object_utils_end

extern function new(string name = "");

// Set the configuration with a single function call.
//
// Width arguments use zero to mean the maximum supported width.
extern virtual function void
set_config(string inst_id = "AXI4",
bit has_manager = 0,
uvm_active_passive_enum manager_active_passive = UVM_PASSIVE,
bit has_subordinate = 0,
uvm_active_passive_enum subordinate_active_passive = UVM_PASSIVE,
int unsigned id_width = 0,
int unsigned addr_width = 0,
int unsigned data_width = 0,
int unsigned user_width = 0,
int unsigned region_width = 0,
int unsigned qos_width = 0);

extern local function int unsigned translate_width(string field_name,
int unsigned max_val,
int unsigned provided);

endclass : axi4_vip_env_cfg

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

function void
axi4_vip_env_cfg::set_config(string inst_id = "AXI4",
bit has_manager = 0,
uvm_active_passive_enum manager_active_passive = UVM_PASSIVE,
bit has_subordinate = 0,
uvm_active_passive_enum subordinate_active_passive = UVM_PASSIVE,
int unsigned id_width = 0,
int unsigned addr_width = 0,
int unsigned data_width = 0,
int unsigned user_width = 0,
int unsigned region_width = 0,
int unsigned qos_width = 0);
m_inst_id = inst_id;
m_has_manager = has_manager;
m_manager_active_passive = manager_active_passive;
m_has_subordinate = has_subordinate;
m_subordinate_active_passive = subordinate_active_passive;

m_id_width = translate_width("id_width", `AXI4_MAX_ID_WIDTH, id_width);
m_addr_width = translate_width("addr_width", `AXI4_MAX_ADDR_WIDTH, addr_width);
m_data_width = translate_width("data_width", `AXI4_MAX_DATA_WIDTH, data_width);
m_user_width = translate_width("user_width", `AXI4_MAX_USER_WIDTH, user_width);
m_region_width = translate_width("region_width", `AXI4_MAX_REGION_WIDTH, region_width);
m_qos_width = translate_width("qos_width", `AXI4_MAX_QOS_WIDTH, qos_width);
endfunction : set_config

function int unsigned axi4_vip_env_cfg::translate_width(string field_name,
int unsigned max_val,
int unsigned provided);
if (provided == 0) begin
return max_val;
end

if (provided > max_val) begin
`uvm_error(m_inst_id,
$sformatf({"Width for %0s cannot be set to %0d. This is greater than %0d ",
"(the maximum supported width for this field)."},
field_name, provided, max_val))
return max_val;
end

return provided;
endfunction : translate_width
146 changes: 146 additions & 0 deletions hw/dv/vip/axi4_vip/axi4_vip_if.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// Copyright lowRISC contributors (COSMIC project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

`include "axi4_vip_defines.svh"

interface axi4_vip_if (
input logic aclk,
input logic aresetn
);

localparam int ID_WIDTH = `AXI4_MAX_ID_WIDTH;
localparam int ADDR_WIDTH = `AXI4_MAX_ADDR_WIDTH;
localparam int DATA_WIDTH = `AXI4_MAX_DATA_WIDTH;
localparam int USER_WIDTH = `AXI4_MAX_USER_WIDTH;
localparam int REGION_WIDTH = `AXI4_MAX_REGION_WIDTH;
localparam int QOS_WIDTH = `AXI4_MAX_QOS_WIDTH;

// write address channel
logic awvalid;
logic awready;
logic [ ID_WIDTH-1:0] awid;
logic [ ADDR_WIDTH-1:0] awaddr;
logic [ 7:0] awlen;
logic [ 2:0] awsize;
logic [ 1:0] awburst;
logic awlock;
logic [ 3:0] awcache;
logic [ 2:0] awprot;
logic [ QOS_WIDTH-1:0] awqos;
logic [ REGION_WIDTH-1:0] awregion;
logic [ USER_WIDTH-1:0] awuser;

// write data channel
logic wvalid;
logic wready;
logic [ DATA_WIDTH-1:0] wdata;
logic [(DATA_WIDTH/8)-1:0] wstrb;
logic wlast;
logic [ USER_WIDTH-1:0] wuser;

// write response channel
logic bvalid;
logic bready;
logic [ ID_WIDTH-1:0] bid;
logic [ 1:0] bresp;
logic [ USER_WIDTH-1:0] buser;

// read address channel
logic arvalid;
logic arready;
logic [ ID_WIDTH-1:0] arid;
logic [ ADDR_WIDTH-1:0] araddr;
logic [ 7:0] arlen;
logic [ 2:0] arsize;
logic [ 1:0] arburst;
logic arlock;
logic [ 3:0] arcache;
logic [ 2:0] arprot;
logic [ QOS_WIDTH-1:0] arqos;
logic [ REGION_WIDTH-1:0] arregion;
logic [ USER_WIDTH-1:0] aruser;

// read data channel
logic rvalid;
logic rready;
logic [ ID_WIDTH-1:0] rid;
logic [ DATA_WIDTH-1:0] rdata;
logic [ 1:0] rresp;
logic rlast;
logic [ USER_WIDTH-1:0] ruser;

// manager clocking block
clocking manager_cb @(posedge aclk);

// write address
output awvalid, awid, awaddr, awlen, awsize, awburst;
Comment thread
rswarbrick marked this conversation as resolved.
output awlock, awcache, awprot, awqos, awregion, awuser;
input awready;

// write data
output wvalid, wdata, wstrb, wlast, wuser;
input wready;

// write response
input bvalid, bid, bresp, buser;
output bready;

// read address
output arvalid, arid, araddr, arlen, arsize, arburst;
output arlock, arcache, arprot, arqos, arregion, aruser;
input arready;

// read data
input rvalid, rid, rdata, rresp, rlast, ruser;
output rready;

endclocking


// subordinate clocking block
clocking subordinate_cb @(posedge aclk);

// write address
input awvalid, awid, awaddr, awlen, awsize, awburst;
input awlock, awcache, awprot, awqos, awregion, awuser;
output awready;

// write data
input wvalid, wdata, wstrb, wlast, wuser;
output wready;

// write response
output bvalid, bid, bresp, buser;
input bready;

// read address
input arvalid, arid, araddr, arlen, arsize, arburst;
input arlock, arcache, arprot, arqos, arregion, aruser;
output arready;

// read data
output rvalid, rid, rdata, rresp, rlast, ruser;
input rready;

endclocking


// monitor clocking block
clocking monitor_cb @(posedge aclk);

input awvalid, awready, awid, awaddr, awlen, awsize, awburst;
input awlock, awcache, awprot, awqos, awregion, awuser;

input wvalid, wready, wdata, wstrb, wlast, wuser;

input bvalid, bready, bid, bresp, buser;

input arvalid, arready, arid, araddr, arlen, arsize, arburst;
input arlock, arcache, arprot, arqos, arregion, aruser;

input rvalid, rready, rid, rdata, rresp, rlast, ruser;

endclocking

endinterface : axi4_vip_if
Loading