예제 #1
0
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
예제 #2
0
 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
예제 #3
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
예제 #4
0
 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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
 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
예제 #8
0
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)
예제 #9
0
 def __init__(self, name, parent):
     super().__init__(name, parent)
     self.analysis_export = UVMAnalysisPort("analysis_imp", self)