Added agent config and random transaction delays
This commit is contained in:
		| @@ -10,10 +10,12 @@ class axi_agent extends uvm_agent; | ||||
|     virtual `AXI_INTF.SUBORDINATE   s_if; | ||||
|     virtual `AXI_INTF               mon_if; | ||||
|  | ||||
|     // Configuration object | ||||
|     rand axi_agent_config   cfg; | ||||
|     // Declare the sequencer and driver | ||||
|     axi_sequencer   sequencer; | ||||
|     axi_driver      driver; | ||||
|     axi_monitor     monitor; | ||||
|     axi_sequencer           sequencer; | ||||
|     axi_driver              driver; | ||||
|     axi_monitor             monitor; | ||||
|  | ||||
|     `uvm_component_utils_begin(axi_agent) | ||||
|         `uvm_field_enum(axi_agent_type_t, agent_type, UVM_DEFAULT) | ||||
| @@ -32,9 +34,21 @@ class axi_agent extends uvm_agent; | ||||
|         `uvm_info("set_agent_type", $sformatf("Agent type set to %s", agent_type.name()), UVM_LOW) | ||||
|     endfunction | ||||
|  | ||||
|     // -------------------------------------------------- | ||||
|     function axi_agent_config get_cfg(); | ||||
|         return cfg; | ||||
|     endfunction | ||||
|  | ||||
|     // -------------------------------------------------- | ||||
|     // Build phase | ||||
|     virtual function void build_phase(uvm_phase phase); | ||||
|         cfg         = axi_agent_config::type_id::create("cfg"); | ||||
|         if (!cfg.randomize()) begin | ||||
|             `uvm_fatal("build_phase", "Randomization of cfg failed") | ||||
|         end else begin | ||||
|             `uvm_info("build_phase", $sformatf("%s randomized:\n%s", cfg.get_full_name(), cfg.sprint()), UVM_LOW) | ||||
|         end | ||||
|  | ||||
|         sequencer   = axi_sequencer::type_id::create("sequencer", this); | ||||
|         if (agent_type == MANAGER) begin | ||||
|             // TODO: Additional variable md should not be needed. We should | ||||
|   | ||||
							
								
								
									
										67
									
								
								src/axi/axi_agent_config.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/axi/axi_agent_config.sv
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| // Configuration class to hold options used in the agent. This contains | ||||
| // options for anything in side the agent | ||||
| class axi_agent_config extends uvm_object; | ||||
|  | ||||
|     /// Minimum value of pre_transaction_delay | ||||
|     int pre_transaction_delay_min = 0; | ||||
|     /// Maximum value of pre_transaction_delay | ||||
|     int pre_transaction_delay_max = 20; | ||||
|  | ||||
|     /// Minimum value of pre_response_delay | ||||
|     int pre_response_delay_min = 1; | ||||
|     /// Maximum value of pre_response_delay | ||||
|     int pre_response_delay_max = 20; | ||||
|  | ||||
|     `uvm_object_utils_begin(axi_agent_config) | ||||
|         `uvm_field_int(pre_transaction_delay_min, UVM_DEFAULT) | ||||
|         `uvm_field_int(pre_transaction_delay_max, UVM_DEFAULT) | ||||
|         `uvm_field_int(pre_response_delay_min, UVM_DEFAULT) | ||||
|         `uvm_field_int(pre_response_delay_max, UVM_DEFAULT) | ||||
|     `uvm_object_utils_end | ||||
|  | ||||
|     // -------------------------------------------------- | ||||
|     function new(string name = "axi_agent_config"); | ||||
|         super.new(name); | ||||
|     endfunction | ||||
|  | ||||
|     // -------------------------------------------------- | ||||
|     function post_randomize(); | ||||
|         `uvm_info("post_randomzie", $sformatf("AXI Agent Config:\n%s", this.sprint()), UVM_LOW) | ||||
|     endfunction | ||||
|  | ||||
|     // TODO: Using $urandom_range() since Verilator does not have support for | ||||
|     // std::randomize() with {} | ||||
|     // -------------------------------------------------- | ||||
|     function int get_pre_transaction_delay(); | ||||
|         int dly = 0; | ||||
|         // if (!std::randomzie(dly) with { | ||||
|         //     dly dist { | ||||
|         //         pre_transaction_delay_min       :/ 4, | ||||
|         //         pre_transaction_delay_max       :/ 4, | ||||
|         //         [pre_transaction_delay_min | ||||
|         //             :pre_transaction_delay_max] :/ 2 | ||||
|         //     }; | ||||
|         // }) begin | ||||
|         //     `uvm_error("get_pre_transaction_delay", "Randomization failed") | ||||
|         // end | ||||
|         dly = $urandom_range(pre_transaction_delay_max, pre_transaction_delay_min); | ||||
|         return dly; | ||||
|     endfunction | ||||
|  | ||||
|     // -------------------------------------------------- | ||||
|     function int get_pre_response_delay(); | ||||
|         int dly = 0; | ||||
|         // if (!std::randomzie(dly) with { | ||||
|         //     dly dist { | ||||
|         //         pre_response_delay_min       :/ 4, | ||||
|         //         pre_response_delay_max       :/ 4, | ||||
|         //         [pre_response_delay_min | ||||
|         //             :pre_response_delay_max] :/ 2 | ||||
|         //     }; | ||||
|         // }) begin | ||||
|         //     `uvm_error("get_pre_response_delay", "Randomization failed") | ||||
|         // end | ||||
|         dly = $urandom_range(pre_response_delay_max, pre_response_delay_min); | ||||
|         return dly; | ||||
|     endfunction | ||||
| endclass | ||||
| @@ -1,10 +1,13 @@ | ||||
| // ---------------------------------------------------------------------- | ||||
| // Driver for AXI transactions | ||||
| // ---------------------------------------------------------------------- | ||||
| typedef axi_agent; | ||||
|  | ||||
| class axi_driver extends uvm_driver; // #(axi_transaction); | ||||
|     virtual `AXI_INTF.MANAGER m_if; | ||||
|     virtual `AXI_INTF.SUBORDINATE s_if; | ||||
|     axi_agent_type_t agent_type; | ||||
|     axi_agent_config cfg; | ||||
|  | ||||
|     `uvm_component_utils(axi_driver) | ||||
|  | ||||
| @@ -24,9 +27,18 @@ class axi_driver extends uvm_driver; // #(axi_transaction); | ||||
|     // -------------------------------------------------- | ||||
|     // Set virtual interfaces | ||||
|     function void set_virtual_interfaces(virtual `AXI_INTF.MANAGER m_if_p, | ||||
|                                         virtual `AXI_INTF.SUBORDINATE s_if_p); | ||||
|                                          virtual `AXI_INTF.SUBORDINATE s_if_p); | ||||
|         `uvm_info("set_virtual_interfaces", $sformatf("Setting virtual interfaces"), UVM_LOW) | ||||
|         m_if = m_if_p; | ||||
|         s_if = s_if_p; | ||||
|     endfunction | ||||
|  | ||||
|     // -------------------------------------------------- | ||||
|     virtual function void end_of_elaboration_phase(uvm_phase phase); | ||||
|         axi_agent agt; | ||||
|  | ||||
|         if ($cast(agt, get_parent())) begin | ||||
|             cfg = agt.get_cfg(); | ||||
|         end | ||||
|     endfunction | ||||
| endclass : axi_driver | ||||
|   | ||||
| @@ -53,8 +53,14 @@ class axi_manager_driver extends axi_driver; | ||||
|  | ||||
|     // ------------------------------------------------------------ | ||||
|     task drive_txn(axi_transaction req); | ||||
|  | ||||
|         int dly = cfg.get_pre_transaction_delay(); | ||||
|         `uvm_info("drive_txn", $sformatf("Driving AXI transaction:\n%s", req.sprint()), UVM_LOW) | ||||
|  | ||||
|         // Pre transaction delay | ||||
|         `uvm_info("drive_txn", $sformatf("Waiting pre_transaction_delay = %0d cycles", | ||||
|             dly), UVM_LOW) | ||||
|         repeat(dly) @(posedge m_if.ACLK); | ||||
|  | ||||
|         if (req.txn_type == AXI_WRITE) begin | ||||
|             drive_write_txn(req); | ||||
|         end else if (req.txn_type == AXI_READ) begin | ||||
|   | ||||
| @@ -5,6 +5,7 @@ package axi_pkg; | ||||
|     `include "uvm_macros.svh" | ||||
|  | ||||
|     // UVM data items | ||||
|     `include "axi_agent_config.sv" | ||||
|     `include "axi_transaction.sv" | ||||
|  | ||||
|     // UVM components | ||||
|   | ||||
| @@ -41,6 +41,7 @@ class axi_subordinate_driver extends axi_driver; | ||||
|     // ------------------------------------------------------------ | ||||
|     task respond_to_write_txn(); | ||||
|         axi_transaction req; | ||||
|         int dly = cfg.get_pre_response_delay(); | ||||
|  | ||||
|         req = axi_transaction::type_id::create("req"); | ||||
|         req.txn_type = AXI_WRITE; | ||||
| @@ -48,25 +49,36 @@ class axi_subordinate_driver extends axi_driver; | ||||
|         req.data = s_if.WDATA; | ||||
|         req.strb = s_if.WSTRB; | ||||
|  | ||||
|         @(posedge s_if.ACLK); | ||||
|         // Pre response delay | ||||
|         `uvm_info("drive_txn", $sformatf("Waiting pre_response_delay = %0d cycles", | ||||
|             dly), UVM_LOW) | ||||
|         repeat(dly) @(posedge s_if.ACLK); | ||||
|  | ||||
|         `uvm_info("respond_to_write_txn", $sformatf("Responding to AXI write transaction:\n%s", req.sprint()), UVM_LOW) | ||||
|  | ||||
|         s_if.AWREADY = 1'b1; | ||||
|         @(posedge s_if.ACLK); | ||||
|         s_if.AWREADY = 1'b0; | ||||
|     endtask | ||||
|  | ||||
|     // ------------------------------------------------------------ | ||||
|     task respond_to_read_txn(); | ||||
|         axi_transaction req; | ||||
|         int dly = cfg.get_pre_response_delay(); | ||||
|  | ||||
|         req = axi_transaction::type_id::create("req"); | ||||
|         req.txn_type = AXI_READ; | ||||
|         req.addr = s_if.ARADDR; | ||||
|  | ||||
|         @(posedge s_if.ACLK); | ||||
|         // Pre response delay | ||||
|         `uvm_info("respond_to_write_txn", $sformatf("Waiting pre_response_delay = %0d cycles", | ||||
|             dly), UVM_LOW) | ||||
|         repeat(dly) @(posedge s_if.ACLK); | ||||
|  | ||||
|         `uvm_info("respond_to_write_txn", $sformatf("Responding to AXI write transaction:\n%s", req.sprint()), UVM_LOW) | ||||
|  | ||||
|         s_if.ARREADY = 1'b1; | ||||
|         @(posedge s_if.ACLK); | ||||
|         s_if.ARREADY = 1'b0; | ||||
|     endtask | ||||
| endclass : axi_subordinate_driver | ||||
|   | ||||
		Reference in New Issue
	
	Block a user