class apb_monitor(UVMMonitor): def __init__(self, name, parent=None): super().__init__(name, parent) self.ap = UVMAnalysisPort("ap", self) # uvm_analysis_port#(apb_rw) self.cfg = None # apb_config self.tr = None # apb_rw self.sigs = None # endfunction: new def build_phase(self, phase): agent = [] if (sv.cast(agent, self.get_parent(), apb_agent) and len(agent) == 1): self.sigs = agent[0].vif else: tmp = [] if (not UVMConfigDb.get(self, "", "vif", tmp)): uvm_fatal( "APB/MON/NOVIF", "No virtual interface specified for self monitor instance") self.sigs = tmp[0] @cocotb.coroutine def run_phase(self, phase): super().run_phase(phase) while True: tr = None # Wait for a SETUP cycle while True: yield Edge(self.sigs.pck) if (self.sigs.pck.psel != 1 or self.sigs.pck.penable != 0): break tr = apb_rw.type_id.create("tr", self) tr.kind = apb_rw.READ if (self.sigs.pck.pwrite): tr.kind = apb_rw.WRITE tr.addr = self.sigs.pck.paddr yield Edge(self.sigs.pck) if (self.sigs.pck.penable != 1): uvm_error( "APB", "APB protocol violation: SETUP cycle not followed by ENABLE cycle" ) tr.data = self.sigs.pck.pwdata if (tr.kind == apb_rw.READ): tr.data = self.sigs.pck.prdata self.trans_observed(tr) uvm_do_callbacks(apb_monitor, apb_monitor_cbs, self.trans_observed(self, tr)) self.ap.write(tr) def trans_observed(self, tr): pass
def __init__(self, name, parent=None): UVMMonitor.__init__(self, name, parent) # cov_trans = new() # cov_trans.set_inst_name({get_full_name(), ".cov_trans"}) # cov_trans_beat = new() # cov_trans_beat.set_inst_name({get_full_name(), ".cov_trans_beat"}) self.trans_collected = ubus_transfer() self.item_collected_port = UVMAnalysisPort("item_collected_port", self) self.addr_ph_imp = UVMBlockingPeekImp("addr_ph_imp", self) # The following two bits are used to control whether checks and coverage are # done both in the monitor class and the interface. self.checks_enable = True self.coverage_enable = True self.vif = None self.master_id = 0
def __init__(self, name, parent): UVMMonitor.__init__(self, name, parent) # cov_trans = new() # cov_trans.set_inst_name({get_full_name(), ".cov_trans"}) # cov_trans_beat = new() # cov_trans_beat.set_inst_name({get_full_name(), ".cov_trans_beat"}) self.trans_collected = ubus_transfer() self.item_collected_port = UVMAnalysisPort("item_collected_port", self) self.state_port = UVMAnalysisPort("state_port", self) self.status = ubus_status("status") # The following property is used to store slave address map # slave_address_map_info slave_addr_map[string] self.slave_addr_map = {} self.checks_enable = True self.coverage_enable = True
def __init__(self, name, parent=None): UVMMonitor.__init__(self, name, parent) # cov_trans = new() # cov_trans.set_inst_name({get_full_name(), ".cov_trans"}) # cov_trans_beat = new() # cov_trans_beat.set_inst_name({get_full_name(), ".cov_trans_beat"}) self.trans_collected = ubus_transfer() self.item_collected_port = UVMAnalysisPort("item_collected_port", self) self.addr_ph_imp = UVMBlockingPeekImp("addr_ph_imp", self) # The following two bits are used to control whether checks and coverage are # done both in the monitor class and the interface. self.checks_enable = True self.coverage_enable = True self.vif = None self.address_phase_grabbed = Event("address_phase_grabbed") # // The following two unsigned integer properties are used by # // check_addr_range() method to detect if a transaction is for this target. self.min_addr = 0x0000 self.max_addr = 0xFFFF
class ubus_master_monitor(UVMMonitor): # # // This property is the virtual interfaced needed for this component to drive # // and view HDL signals. # protected virtual ubus_if vif # # // The following two bits are used to control whether checks and coverage are # // done both in the monitor class and the interface. # bit checks_enable = 1 # bit coverage_enable = 1 # # uvm_analysis_port #(ubus_transfer) item_collected_port # # // The following property holds the transaction information currently # // begin captured (by the collect_address_phase and data_phase methods). # protected ubus_transfer trans_collected # # // Fields to hold trans addr, data and wait_state. # protected bit [15:0] addr # protected bit [7:0] data # protected int unsigned wait_state # # // Transfer collected covergroup # covergroup cov_trans # option.per_instance = 1 # trans_start_addr : coverpoint trans_collected.addr { # option.auto_bin_max = 16; } # trans_dir : coverpoint trans_collected.read_write # trans_size : coverpoint trans_collected.size { # bins sizes[] = {1, 2, 4, 8} # illegal_bins invalid_sizes = default; } # trans_addrXdir : cross trans_start_addr, trans_dir # trans_dirXsize : cross trans_dir, trans_size # endgroup : cov_trans # # // Transfer collected beat covergroup # covergroup cov_trans_beat # option.per_instance = 1 # beat_addr : coverpoint addr { # option.auto_bin_max = 16; } # beat_dir : coverpoint trans_collected.read_write # beat_data : coverpoint data { # option.auto_bin_max = 8; } # beat_wait : coverpoint wait_state { # bins waits[] = { [0:9] } # bins others = { [10:$] }; } # beat_addrXdir : cross beat_addr, beat_dir # beat_addrXdata : cross beat_addr, beat_data # endgroup : cov_trans_beat # # // Provide implementations of virtual methods such as get_type_name and create # `uvm_component_utils_begin(ubus_master_monitor) # `uvm_field_int(master_id, UVM_DEFAULT) # `uvm_field_int(checks_enable, UVM_DEFAULT) # `uvm_field_int(coverage_enable, UVM_DEFAULT) # `uvm_component_utils_end # def __init__(self, name, parent=None): UVMMonitor.__init__(self, name, parent) # cov_trans = new() # cov_trans.set_inst_name({get_full_name(), ".cov_trans"}) # cov_trans_beat = new() # cov_trans_beat.set_inst_name({get_full_name(), ".cov_trans_beat"}) self.trans_collected = ubus_transfer() self.item_collected_port = UVMAnalysisPort("item_collected_port", self) self.addr_ph_imp = UVMBlockingPeekImp("addr_ph_imp", self) # The following two bits are used to control whether checks and coverage are # done both in the monitor class and the interface. self.checks_enable = True self.coverage_enable = True self.vif = None self.master_id = 0 # endfunction : new def build_phase(self, phase): arr = [] if UVMConfigDb.get(self, "", "vif", arr): self.vif = arr[0] if self.vif is None: self.uvm_report_fatal( "NOVIF", "virtual interface must be set for: " + self.get_full_name() + ".vif") arr = [] if UVMConfigDb.get(self, "", "master_id", arr): self.master_id = arr[0] async def run_phase(self, phase): self.uvm_report_info(self.get_full_name() + " MASTER ID", sv.sformatf(" = %0d", self.master_id), UVM_MEDIUM) # fork forked_proc = cocotb.fork(self.collect_transactions()) # join await forked_proc # endtask : run_phase # // collect_transactions async def collect_transactions(self): await Timer(0, "NS") while True: await RisingEdge(self.vif.sig_clock) if (self.m_parent is not None): self.trans_collected.master = self.m_parent.get_name() await self.collect_arbitration_phase() await self.collect_address_phase() await self.collect_data_phase() uvm_info( self.get_full_name(), sv.sformatf("Transfer collected :\n%s", self.trans_collected.sprint()), UVM_MEDIUM) if (self.checks_enable): self.perform_transfer_checks() if (self.coverage_enable): self.perform_transfer_coverage() self.item_collected_port.write(self.trans_collected) # endtask : collect_transactions # // collect_arbitration_phase async def collect_arbitration_phase(self): # @(posedge vif.sig_request[master_id]) # @(posedge vif.sig_clock iff vif.sig_grant[master_id] === 1) while True: await RisingEdge(self.vif.sig_request) sig_req = self.vif.sig_req[self.master_id] if sig_req == 1: break while True: await RisingEdge(self.vif.sig_clock) grant = int(self.vif.sig_gnt[self.master_id]) if grant == 1: break self.begin_tr(self.trans_collected) # endtask : collect_arbitration_phase # // collect_address_phase # virtual protected task collect_address_phase() async def collect_address_phase(self): await RisingEdge(self.vif.sig_clock) self.trans_collected.addr = int(self.vif.sig_addr.value) sig_size = int(self.vif.sig_size) #case (vif.sig_size) if sig_size == 0: self.trans_collected.size = 1 elif sig_size == 1: self.trans_collected.size = 2 elif sig_size == 2: self.trans_collected.size = 4 elif sig_size == 3: self.trans_collected.size = 8 self.trans_collected.data = [0] * self.trans_collected.size sig_read = int(self.vif.sig_read) sig_write = int(self.vif.sig_write) read_write = sig_read << 1 | sig_write if read_write == 0: self.trans_collected.read_write = NOP elif read_write == 2: self.trans_collected.read_write = READ elif read_write == 1: self.trans_collected.read_write = WRITE # endtask : collect_address_phase # // collect_data_phase async def collect_data_phase(self): if (self.trans_collected.read_write != NOP): for i in range(self.trans_collected.size): while True: await RisingEdge(self.vif.sig_clock) if self.vif.sig_wait.value == 0: break self.trans_collected.data[i] = self.vif.sig_data.value self.end_tr(self.trans_collected) # endtask : collect_data_phase def perform_transfer_checks(self): self.check_transfer_size() self.check_transfer_data_size() # // check_transfer_size def check_transfer_size(self): trans_collected = self.trans_collected if (trans_collected.size == 1 or trans_collected.size == 2 or trans_collected.size == 4 or trans_collected.size == 8): pass else: uvm_error(self.get_type_name(), "Invalid transfer size!") # // check_transfer_data_size def check_transfer_data_size(self): if (self.trans_collected.size != len(self.trans_collected.data)): uvm_error(self.get_type_name(), "Transfer size field / data size mismatch.") # // perform_transfer_coverage # virtual protected function void perform_transfer_coverage() # cov_trans.sample() # for (int unsigned i = 0; i < trans_collected.size; i++) begin # addr = trans_collected.addr + i # data = trans_collected.data[i] #//Wait state is not currently monitored #// wait_state = trans_collected.wait_state[i] # cov_trans_beat.sample() # end # endfunction : perform_transfer_coverage def perform_transfer_coverage(self): pass # TODO
class ubus_bus_monitor(UVMMonitor): # # // The virtual interface used to view HDL signals. # protected virtual ubus_if vif # # // Property indicating the number of transactions occuring on the ubus. # protected int unsigned num_transactions = 0 # # // The following two bits are used to control whether checks and coverage are # // done both in the bus monitor class and the interface. # bit checks_enable = 1 # bit coverage_enable = 1 # # // Analysis ports for the item_collected and state notifier. # uvm_analysis_port #(ubus_transfer) item_collected_port # uvm_analysis_port #(ubus_status) state_port # # // The state of the ubus # protected ubus_status status # # // The following property holds the transaction information currently # // being captured (by the collect_address_phase and data_phase methods). # protected ubus_transfer trans_collected # # // Events needed to trigger covergroups # protected event cov_transaction # protected event cov_transaction_beat # # // Fields to hold trans data and wait_state. No coverage of dynamic arrays. # protected bit [15:0] addr # protected bit [7:0] data # protected int unsigned wait_state # # // Transfer collected covergroup # covergroup cov_trans @cov_transaction # option.per_instance = 1 # trans_start_addr : coverpoint trans_collected.addr { # option.auto_bin_max = 16; } # trans_dir : coverpoint trans_collected.read_write # trans_size : coverpoint trans_collected.size { # bins sizes[] = {1, 2, 4, 8} # illegal_bins invalid_sizes = default; } # trans_addrXdir : cross trans_start_addr, trans_dir # trans_dirXsize : cross trans_dir, trans_size # endgroup : cov_trans # # // Transfer collected data covergroup # covergroup cov_trans_beat @cov_transaction_beat # option.per_instance = 1 # beat_addr : coverpoint addr { # option.auto_bin_max = 16; } # beat_dir : coverpoint trans_collected.read_write # beat_data : coverpoint data { # option.auto_bin_max = 8; } # beat_wait : coverpoint wait_state { # bins waits[] = { [0:9] } # bins others = { [10:$] }; } # beat_addrXdir : cross beat_addr, beat_dir # beat_addrXdata : cross beat_addr, beat_data # endgroup : cov_trans_beat # # // new - constructor def __init__(self, name, parent): UVMMonitor.__init__(self, name, parent) # cov_trans = new() # cov_trans.set_inst_name({get_full_name(), ".cov_trans"}) # cov_trans_beat = new() # cov_trans_beat.set_inst_name({get_full_name(), ".cov_trans_beat"}) self.trans_collected = ubus_transfer() self.item_collected_port = UVMAnalysisPort("item_collected_port", self) self.state_port = UVMAnalysisPort("state_port", self) self.status = ubus_status("status") # The following property is used to store slave address map # slave_address_map_info slave_addr_map[string] self.slave_addr_map = {} self.checks_enable = True self.coverage_enable = True # endfunction : new # // set_slave_configs def set_slave_configs(self, slave_name, min_addr=0, max_addr=0): self.slave_addr_map[slave_name] = slave_address_map_info() self.slave_addr_map[slave_name].set_address_map(min_addr, max_addr) # endfunction : set_slave_configs def build_phase(self, phase): vif = [] if not (UVMConfigDb.get(self, "", "vif", vif)): uvm_fatal("NOVIF", ("virtual interface must be set for: " + self.get_full_name() + ".vif")) self.vif = vif[0] # // run phase @cocotb.coroutine def run_phase(self, phase): # fork reset_proc = cocotb.fork(self.observe_reset()) collect_proc = cocotb.fork(self.collect_transactions()) # join yield [reset_proc, collect_proc.join()] # endtask : run_phase # # // observe_reset @cocotb.coroutine def observe_reset(self): # fork @cocotb.coroutine def rst_start(): while True: yield RisingEdge(self.vif.sig_reset) self.status.bus_state = RST_START self.state_port.write(self.status) @cocotb.coroutine def rst_stop(): while True: yield RisingEdge(self.vif.sig_reset) self.status.bus_state = RST_STOP self.state_port.write(self.status) start_proc = cocotb.fork(rst_start()) stop_proc = cocotb.fork(rst_stop()) yield [start_proc, stop_proc.join()] # join # endtask : observe_reset # // collect_transactions @cocotb.coroutine def collect_transactions(self): while True: yield self.collect_arbitration_phase() yield self.collect_address_phase() yield self.collect_data_phase() uvm_info("UBUS_MON", sv.sformatf("Transfer collected :\n%s", self.trans_collected.sprint()), UVM_HIGH) if (self.checks_enable): self.perform_transfer_checks() if (self.coverage_enable): self.perform_transfer_coverage() self.item_collected_port.write(self.trans_collected) # endtask : collect_transactions # // collect_arbitration_phase @cocotb.coroutine def collect_arbitration_phase(self): tmpStr = "" # @(posedge vif.sig_clock iff (vif.sig_grant != 0)) while True: yield RisingEdge(self.vif.sig_clock) if self.vif.sig_grant != 0: break self.status.bus_state = ARBI self.state_port.write(self.status) self.begin_tr(self.trans_collected) # Check which grant is asserted to determine which master is performing # the transfer on the bus. #for (int j = 0; j <= 15; j++): for j in range(16): if (self.vif.sig_grant.value[j] == 1): tmpStr = sv.sformatf("masters[%0d]", j) self.trans_collected.master = tmpStr break # endtask : collect_arbitration_phase # # // collect_address_phase @cocotb.coroutine def collect_address_phase(self): yield RisingEdge(self.vif.sig_clock) self.trans_collected.addr = int(self.vif.sig_addr.value) sig_size = int(self.vif.sig_size) if sig_size == 0: self.trans_collected.size = 1 elif sig_size == 1: self.trans_collected.size = 2 elif sig_size == 2: self.trans_collected.size = 4 elif sig_size == 3: self.trans_collected.size = 8 self.trans_collected.data = [0] * self.trans_collected.size vec = int((int(self.vif.sig_read) << 1) & int(self.vif.sig_write)) if vec == 0: self.trans_collected.read_write = NOP self.status.bus_state = NO_OP self.state_port.write(self.status) elif vec == 1: self.trans_collected.read_write = READ self.status.bus_state = ADDR_PH self.state_port.write(self.status) elif vec == 2: self.trans_collected.read_write = WRITE self.status.bus_state = ADDR_PH self.state_port.write(self.status) elif vec == 3: self.status.bus_state = ADDR_PH_ERROR self.state_port.write(self.status) if (self.checks_enable): uvm_error(self.get_type_name(), "Read and Write true at the same time") # endtask : collect_address_phase # # // collect_data_phase @cocotb.coroutine def collect_data_phase(self): if (self.trans_collected.read_write != NOP): self.check_which_slave() for i in range(self.trans_collected.size): self.status.bus_state = DATA_PH self.state_port.write(self.status) while True: yield RisingEdge(self.vif.sig_clock) if self.vif.sig_wait == 0: break self.trans_collected.data[i] = self.vif.sig_data self.num_transactions += 1 self.end_tr(self.trans_collected) else: yield Timer(0) # endtask : collect_data_phase # # // check_which_slave def check_which_slave(self): slave_name = "" slave_found = False for slave_name in self.slave_addr_map: if (self.slave_addr_map[slave_name].get_min_addr() <= self.trans_collected.addr and self.trans_collected.addr <= self.slave_addr_map[slave_name].get_max_addr()): self.trans_collected.slave = slave_name self.slave_found = True if self.slave_found is True: break if slave_found is False: uvm_error(self.get_type_name(), sv.sformatf("Master attempted a transfer at illegal address 16'h%0h", self.trans_collected.addr)) # endfunction : check_which_slave # # // perform_transfer_checks def perform_transfer_checks(self): self.check_transfer_size() self.check_transfer_data_size() # endfunction : perform_transfer_checks # // check_transfer_size def check_transfer_size(self): pass # if (trans_collected.read_write != NOP): # assert_transfer_size : assert(trans_collected.size == 1 || # trans_collected.size == 2 || trans_collected.size == 4 || # trans_collected.size == 8) else begin # `uvm_error(get_type_name(), # "Invalid transfer size!") # end # end # endfunction : check_transfer_size # // check_transfer_data_size def check_transfer_data_size(self): pass # if (trans_collected.size != trans_collected.data.size()) # `uvm_error(get_type_name(), # "Transfer size field / data size mismatch.") # endfunction : check_transfer_data_size # // perform_transfer_coverage def perform_transfer_coverage(self): pass
def __init__(self, name, parent=None): super().__init__(name, parent) self.ap = UVMAnalysisPort("ap", self) # uvm_analysis_port#(apb_rw) self.cfg = None # apb_config self.tr = None # apb_rw self.sigs = None
class ubus_slave_monitor(UVMMonitor): # // This property is the virtual interface needed for this component to drive # // and view HDL signals. # protected virtual ubus_if self.vif # # # // The following property holds the transaction information currently # // begin captured (by the collect_address_phase and data_phase methods). # protected ubus_transfer trans_collected # # // monitor notifier that the address phase (and full item) has been collected # # // Events needed to trigger covergroups # protected event cov_transaction # protected event cov_transaction_beat # # // Fields to hold trans data and wait_state. No coverage of dynamic arrays. # protected bit [15:0] addr # protected bit [7:0] data # protected int unsigned wait_state # # // Transfer collected covergroup # covergroup cov_trans # option.per_instance = 1 # trans_start_addr : coverpoint trans_collected.addr { # option.auto_bin_max = 16; } # trans_dir : coverpoint trans_collected.read_write # trans_size : coverpoint trans_collected.size { # bins sizes[] = {1, 2, 4, 8} # illegal_bins invalid_sizes = default; } # trans_addrXdir : cross trans_start_addr, trans_dir # trans_dirXsize : cross trans_dir, trans_size # endgroup : cov_trans # # // Transfer collected data covergroup # covergroup cov_trans_beat # option.per_instance = 1 # beat_addr : coverpoint addr { # option.auto_bin_max = 16; } # beat_dir : coverpoint trans_collected.read_write # beat_data : coverpoint data { # option.auto_bin_max = 8; } # beat_wait : coverpoint wait_state { # bins waits[] = { [0:9] } # bins others = { [10:$] }; } # beat_addrXdir : cross beat_addr, beat_dir # beat_addrXdata : cross beat_addr, beat_data # endgroup : cov_trans_beat # # // new - constructor def __init__(self, name, parent=None): UVMMonitor.__init__(self, name, parent) # cov_trans = new() # cov_trans.set_inst_name({get_full_name(), ".cov_trans"}) # cov_trans_beat = new() # cov_trans_beat.set_inst_name({get_full_name(), ".cov_trans_beat"}) self.trans_collected = ubus_transfer() self.item_collected_port = UVMAnalysisPort("item_collected_port", self) self.addr_ph_imp = UVMBlockingPeekImp("addr_ph_imp", self) # The following two bits are used to control whether checks and coverage are # done both in the monitor class and the interface. self.checks_enable = True self.coverage_enable = True self.vif = None self.address_phase_grabbed = Event("address_phase_grabbed") # // The following two unsigned integer properties are used by # // check_addr_range() method to detect if a transaction is for this target. self.min_addr = 0x0000 self.max_addr = 0xFFFF # endfunction : new def build_phase(self, phase): arr = [] if UVMConfigDb.get(self, "", "vif", arr): self.vif = arr[0] if self.vif is None: self.uvm_report_fatal( "NOVIF", "virtual interface must be set for: " + self.get_full_name() + ".vif") # endfunction: build_phase # // set the monitor's address range # function void set_addr_range(bit [15:0] min_addr, bit [15:0] max_addr) # this.min_addr = min_addr # this.max_addr = max_addr # endfunction : set_addr_range # # // get the monitor's min addr # function bit [15:0] get_min_addr() # return min_addr # endfunction : get_min_addr # # // get the monitor's max addr # function bit [15:0] get_max_addr() # return max_addr # endfunction : get_max_addr @cocotb.coroutine def run_phase(self, phase): # fork forked_proc = cocotb.fork(self.collect_transactions()) # join yield forked_proc # endtask : run_phase # collect_transactions @cocotb.coroutine def collect_transactions(self): yield RisingEdge(self.vif.sig_reset) range_check = False while True: if (self.m_parent is not None): self.trans_collected.slave = self.m_parent.get_name() yield self.collect_address_phase() range_check = self.check_addr_range() if (range_check): self.begin_tr(self.trans_collected) self.address_phase_grabbed.set() yield self.collect_data_phase() uvm_info( self.get_type_name(), sv.sformatf("Transfer collected :\n%s", self.trans_collected.sprint()), UVM_FULL) if (self.checks_enable): self.perform_transfer_checks() if self.coverage_enable: self.perform_transfer_coverage() self.item_collected_port.write(self.trans_collected) # endtask : collect_transactions # // check_addr_range def check_addr_range(self): if ((self.trans_collected.addr >= self.min_addr) and (self.trans_collected.addr <= self.max_addr)): return True return False # endfunction : check_addr_range # // collect_address_phase @cocotb.coroutine def collect_address_phase(self): found = False while found is False: yield RisingEdge(self.vif.sig_clock) if self.vif.sig_read.value.is_resolvable and self.vif.sig_write.value.is_resolvable: if self.vif.sig_read.value == 1 or self.vif.sig_write.value == 1: addr = int(self.vif.sig_addr) self.trans_collected.addr = addr if self.vif.sig_size.value == 0: self.trans_collected.size = 1 elif self.vif.sig_size.value == 1: self.trans_collected.size = 2 elif self.vif.sig_size.value == 2: self.trans_collected.size = 4 elif self.vif.sig_size.value == 3: self.trans_collected.size = 8 self.trans_collected.data = [0] * self.trans_collected.size if self.vif.sig_read.value == 0 and self.vif.sig_write.value == 0: self.trans_collected.read_write = NOP elif self.vif.sig_read.value == 1 and self.vif.sig_write.value == 0: self.trans_collected.read_write = READ elif self.vif.sig_read.value == 0 and self.vif.sig_write.value == 1: self.trans_collected.read_write = WRITE found = True # endtask : collect_address_phase # # // collect_data_phase @cocotb.coroutine def collect_data_phase(self): if (self.trans_collected.read_write != NOP): for i in range(self.trans_collected.size): while True: yield RisingEdge(self.vif.sig_clock) if self.vif.sig_wait.value == 0: break self.trans_collected.data[i] = self.vif.sig_data.value self.end_tr(self.trans_collected) # endtask : collect_data_phase # # // perform_transfer_checks def perform_transfer_checks(self): self.check_transfer_size() self.check_transfer_data_size() # # // check_transfer_size def check_transfer_size(self): trans_collected = self.trans_collected if (trans_collected.size == 1 or trans_collected.size == 2 or trans_collected.size == 4 or trans_collected.size == 8): pass else: uvm_error(self.get_type_name(), "Invalid transfer size!") # endfunction : check_transfer_size # // check_transfer_data_size def check_transfer_data_size(self): if (self.trans_collected.size != len(self.trans_collected.data)): uvm_error(self.get_type_name(), "Transfer size field / data size mismatch.") # // perform_transfer_coverage def perform_transfer_coverage(self): pass # TODO # cov_trans.sample() # for (int unsigned i = 0; i < trans_collected.size; i++): # addr = trans_collected.addr + i # data = trans_collected.data[i] #//Wait state inforamtion is not currently monitored. #// wait_state = trans_collected.wait_state[i] # cov_trans_beat.sample() # end # endfunction : perform_transfer_coverage @cocotb.coroutine def peek(self, trans): _print("in blocking peek yielding to grabbed_wait") yield self.address_phase_grabbed.wait() self.address_phase_grabbed.clear() _print("in blocking peek AFTER grabbed_wait: " + self.trans_collected.convert2string()) trans.append(self.trans_collected)
def __init__(self, name, parent): super().__init__(name, parent) self.analysis_export = UVMAnalysisPort("analysis_imp", self)