EDA Playground lets you type in and run HDL code (using a selection of free and commercial simulators and synthesizers).
It's great for learning HDLs, it's great for testing out unfamiliar things and it's great for sharing code.
You can start typing straight away. But to run your code, you'll need to sign or log in. Logging in with a Google account gives you access to all non-commercial simulators and some commercial simulators:
To run commercial simulators, you need to register and log in with a username and password. Registration is free, and only pre-approved email's will have access to the commercial simulators.
* not available.
206
//-------------------------------------------
// Top level Test module
// Includes all env component and sequences files
//-------------------------------------------
import uvm_pkg::*;
`include "uvm_macros.svh"
//Include all files
`include "apb_if.svh"
`include "apb_rw.svh"
`include "apb_driver_seq_mon.svh"
`include "apb_agent_env_config.svh"
`include "apb_sequences.svh"
`include "apb_test.svh"
//--------------------------------------------------------
//Top level module that instantiates just a physical apb interface
//No real DUT or APB slave as of now
//--------------------------------------------------------
module test;
import uvm_pkg::*;
logic [31:0] paddr;
logic psel;
logic penable;
logic pwrite;
logic [31:0] prdata;
logic [31:0] pwdata;
logic pclk;
initial begin
pclk=0;
end
//Generate a clock
always begin
#10 pclk = ~pclk;
end
//Instantiate a physical interface for APB interface here and connect the pclk input
initial begin
//Pass above physical interface to test top
//(which will further pass it down to env->agent->drv/sqr/mon
//Call the run_test - but passing run_test argument as test class name
end
endmodule
xxxxxxxxxx
//-----------------------------
// This file contains apb config, apb_agent and apb_env class components
//-----------------------------
`ifndef APB_AGENT_ENV_CFG__SV
`define APB_AGENT_ENV_CFG__SV
//---------------------------------------
// APB Config class
// -Not really done anything as of now
//---------------------------------------
class apb_config extends uvm_object;
`uvm_object_utils(apb_config)
virtual apb_if vif;
function new(string name="apb_config");
super.new(name);
endfunction
endclass
//---------------------------------------
// APB Agent class
//---------------------------------------
class apb_agent extends uvm_agent;
//Agent will have the sequencer, driver and monitor components for the APB interface
apb_sequencer sqr;
apb_master_drv drv;
apb_monitor mon;
virtual apb_if vif;
`uvm_component_utils(apb_agent)
function new(string name, uvm_component parent = null);
super.new(name, parent);
endfunction
//Build phase of agent - construct sequencer, driver and monitor
//get handle to virtual interface from env (parent) config_db
//and pass handle down to srq/driver/monitor
virtual function void build_phase(uvm_phase phase);
endfunction: build_phase
//Connect - driver and sequencer port to export
virtual function void connect_phase(uvm_phase phase);
uvm_report_info("apb_agent::", "connect_phase, Connected driver to sequencer");
endfunction
endclass: apb_agent
//----------------------------------------------
// APB Env class
//----------------------------------------------
class apb_env extends uvm_env;
`uvm_component_utils(apb_env);
//ENV class will have agent as its sub component
apb_agent agt;
//virtual interface for APB interface
virtual apb_if vif;
function new(string name, uvm_component parent = null);
super.new(name, parent);
endfunction
//Build phase - Construct agent and get virtual interface handle from test and pass it down to agent
function void build_phase(uvm_phase phase);
endfunction
endclass : apb_env
`endif
xxxxxxxxxx
//----------------------------------------------------
// This file contains the APB Driver, Sequencer and Monitor component classes defined
//----------------------------------------------------
`ifndef APB_DRV_SEQ_MON_SV
`define APB_DRV_SEQ_MON_SV
typedef apb_config;
typedef apb_agent;
//---------------------------------------------
// APB master driver Class
//---------------------------------------------
class apb_master_drv extends uvm_driver#(apb_rw);
`uvm_component_utils(apb_master_drv)
virtual apb_if vif;
apb_config cfg;
function new(string name,uvm_component parent = null);
super.new(name,parent);
endfunction
//Build Phase
//Get the virtual interface handle form the agent (parent ) or from config_db
function void build_phase(uvm_phase phase);
endfunction
//Run Phase
//Implement the Driver -Sequencer API to get an item
//Based on if it is Read/Write - drive on APB interface the corresponding pins
virtual task run_phase(uvm_phase phase);
endtask: run_phase
virtual protected task drive_read(input bit [31:0] addr,
output logic [31:0] data);
endtask: drive_read
virtual protected task drive_write(input bit [31:0] addr,
input bit [31:0] data);
endtask: drive_write
endclass: apb_master_drv
//---------------------------------------------
// APB Sequencer Class
// Derive form uvm_sequencer and parameterize to apb_rw sequence item
//---------------------------------------------
class apb_sequencer extends uvm_sequencer #(apb_rw);
`uvm_component_utils(apb_sequencer)
function new(input string name, uvm_component parent=null);
super.new(name, parent);
endfunction : new
endclass : apb_sequencer
//-----------------------------------------
// APB Monitor class
//-----------------------------------------
class apb_monitor extends uvm_monitor;
virtual apb_if.passive vif;
//Analysis port -parameterized to apb_rw transaction
///Monitor writes transaction objects to this port once detected on interface
uvm_analysis_port#(apb_rw) ap;
//config class handle
apb_config cfg;
`uvm_component_utils(apb_monitor)
function new(string name, uvm_component parent = null);
super.new(name, parent);
//Create Analysis port here
endfunction: new
//Build Phase - Get handle to virtual if from agent/config_db
virtual function void build_phase(uvm_phase phase);
endfunction
virtual task run_phase(uvm_phase phase);
endtask : run_phase
endclass: apb_monitor
`endif
xxxxxxxxxx
//------------------------------------
//APB (Advanced peripheral Bus) Interface
//
//------------------------------------
`ifndef APB_IF_SV
`define APB_IF_SV
interface apb_if(input bit pclk);
wire [31:0] paddr;
wire psel;
wire penable;
wire pwrite;
wire [31:0] prdata;
wire [31:0] pwdata;
//Master Clocking block - used for Drivers
clocking master_cb @(posedge pclk);
endclocking: master_cb
//Slave Clocking Block - used for any Slave BFMs
clocking slave_cb @(posedge pclk);
endclocking: slave_cb
//Monitor Clocking block - For sampling by monitor components
clocking monitor_cb @(posedge pclk);
endclocking: monitor_cb
modport master(clocking master_cb);
modport slave(clocking slave_cb);
modport passive(clocking monitor_cb);
endinterface: apb_if
`endif
xxxxxxxxxx
//------------------------------------
// Basic APB Read/Write Transaction class definition
// This transaction will be used by Sequences, Drivers and Monitors
//------------------------------------
`ifndef APB_RW_SV
`define APB_RW_SV
//apb_rw sequence item derived from base uvm_sequence_item
class apb_rw extends uvm_sequence_item;
//typedef for READ/Write transaction type
typedef enum {READ, WRITE} kind_e;
rand bit [31:0] addr; //Address
rand logic [31:0] data; //Data - For write or read response
rand kind_e apb_cmd; //command type
//Register with factory for dynamic creation
`uvm_object_utils(apb_rw)
function new (string name = "apb_rw");
super.new(name);
endfunction
function string convert2string();
// ??
endfunction
endclass: apb_rw
`endif
xxxxxxxxxx
//A few flavours of apb sequences
`ifndef APB_SEQUENCES_SV
`define APB_SEQUENCES_SV
//------------------------
//Base APB sequence derived from uvm_sequence and parameterized with sequence item of type apb_rw
//------------------------
class apb_base_seq extends uvm_sequence#(apb_rw);
`uvm_object_utils(apb_base_seq)
function new(string name ="");
super.new(name);
endfunction
//Main Body method that gets executed once sequence is started
task body();
endtask
endclass
`endif
`ifndef APB_BASE_TEST_SV
`define APB_BASE_TEST_SV
//--------------------------------------------------------
//Top level Test class that instantiates env, configures and starts stimulus
//--------------------------------------------------------
class apb_base_test extends uvm_test;
//Register with factory
`uvm_component_utils(apb_base_test);
apb_env env;
apb_config cfg;
virtual apb_if vif;
function new(string name = "apb_base_test", uvm_component parent = null);
super.new(name, parent);
endfunction
//Build phase - Construct the cfg and env class using factory
//Get the virtual interface handle from Test and then set it config db for the env component
function void build_phase(uvm_phase phase);
endfunction
//Run phase - Create an abp_sequence and start it on the apb_sequencer
task run_phase( uvm_phase phase );
apb_base_seq apb_seq;
endtask: run_phase
endclass
`endif
xxxxxxxxxx
// Code your design here
Your account is not validated. If you wish to use commercial simulators, you need a validated account.
If you have already registered (or have recently changed your email address), but have not clicked on the link in the email we sent you, please do so. If you cannot find the email, please check your spam/junk folder. Or click here to resend the email.
If you have not already registered for a full account, you can do so by clicking below. You will then need to provide us with some identification information. You may wish to save your code first.
Creating, deleting, and renaming files is not supported during Collaboration. To encourage development of these features for Collaboration, tweet to @EDAPlayground
This playground may have been modified. Please save or copy before starting collaboration.
Your exercise has been submitted.