OpenCores
URL https://opencores.org/ocsvn/lpffir/lpffir/trunk

Subversion Repositories lpffir

[/] [lpffir/] [trunk/] [uvm/] [tools/] [uvm_syoscb/] [src/] [cl_syoscb.svh] - Rev 4

Compare with Previous | Blame | View Log

//----------------------------------------------------------------------
//   Copyright 2014-2015 SyoSil ApS
//   All Rights Reserved Worldwide
//
//   Licensed under the Apache License, Version 2.0 (the
//   "License"); you may not use this file except in
//   compliance with the License.  You may obtain a copy of
//   the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in
//   writing, software distributed under the License is
//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
//   CONDITIONS OF ANY KIND, either express or implied.  See
//   the License for the specific language governing
//   permissions and limitations under the License.
//----------------------------------------------------------------------
/// Top level class implementing the root of the SyoSil UVM scoreboard
class cl_syoscb extends uvm_scoreboard;
  //-------------------------------------
  // Non randomizable variables
  //-------------------------------------
  /// Handle to the global UVM scoreboard configuration
  local cl_syoscb_cfg cfg;

  /// Array holding handles to all queues
  local cl_syoscb_queue queues[];

  // Handle to the compare strategy
  local cl_syoscb_compare compare_strategy;

  // Assoc array holding each uvm_subscriber
  local cl_syoscb_subscriber subscribers[string];

  //-------------------------------------
  // UVM Macros
  //-------------------------------------
  `uvm_component_utils_begin(cl_syoscb)
    `uvm_field_object(cfg,                   UVM_DEFAULT)
    `uvm_field_array_object(queues,          UVM_DEFAULT)
    `uvm_field_object(compare_strategy,      UVM_DEFAULT)
    `uvm_field_aa_object_string(subscribers, UVM_DEFAULT)
  `uvm_component_utils_end

  //-------------------------------------
  // Constructor
  //-------------------------------------
  extern function new(string name = "cl_syoscb", uvm_component parent = null);

  //-------------------------------------
  // UVM Phase methods
  //-------------------------------------
  extern function void build_phase(uvm_phase phase);

  //-------------------------------------
  // Function based API
  //-------------------------------------
  extern function void add_item(string queue_name, string producer, uvm_sequence_item item);
  extern function void compare();

  //-------------------------------------
  // Transaction based API
  //-------------------------------------
  extern function cl_syoscb_subscriber get_subscriber(string queue_name, string producer);
endclass: cl_syoscb

function cl_syoscb::new(string name = "cl_syoscb", uvm_component parent = null);
   super.new(name, parent);
endfunction : new

/// The build_phase gets the scoreboard configuration and forwards it to the child components (cl_syoscb_queue
/// and cl_syoscb_compare). Additionally, it creates all of the queues defined in the configuration object. Finally,
/// it also creates the compare strategy via a factory create call.
function void cl_syoscb::build_phase(uvm_phase phase);
  if (!uvm_config_db #(cl_syoscb_cfg)::get(this, "", "cfg", this.cfg)) begin
    // *NOTE*: If no cfg object is given then no scb name is available
    //         Thus, no scb name is printed here
    `uvm_fatal("CFG_ERROR", "Configuration object not passed.")
  end

  // Set the default SCB name if not specified explicitly
  if(this.cfg.get_scb_name() == "") begin
    this.cfg.set_scb_name(this.get_name());
  end
  
  // Create list of queues
  this.queues = new[this.cfg.size_queues()];

  // Create the queues as defined in the configuration
  begin
    string queue_names[];

    // Get teh list of queue names
    this.cfg.get_queues(queue_names);

    foreach(queue_names[i]) begin
      this.queues[i] = cl_syoscb_queue::type_id::create(queue_names[i], this);
      this.cfg.set_queue(queue_names[i], this.queues[i]);

      // Forward the configuration to the queue
      uvm_config_db #(cl_syoscb_cfg)::set(this, queue_names[i], "cfg", this.cfg); 
    end
  end

  // Forward the configuration to the compare_strategy
  uvm_config_db #(cl_syoscb_cfg)::set(this, "compare_strategy", "cfg", this.cfg); 

  // Create the compare strategy
  this.compare_strategy = cl_syoscb_compare::type_id::create(.name("compare_strategy"), .parent(this));

  begin
    cl_syoscb_report_catcher catcher = new();
    uvm_report_cb::add(null, catcher);
  end

  begin
    string producers[];

    this.cfg.get_producers(producers);

    foreach(producers[i]) begin
      cl_syoscb_cfg_pl pl = this.cfg.get_producer(producers[i]);

      foreach(pl.list[j]) begin
        cl_syoscb_subscriber subscriber;

        subscriber = cl_syoscb_subscriber::type_id::create({producers[i], "_", pl.list[j], "_subscr"}, this);
        subscriber.set_queue_name(pl.list[j]);
        subscriber.set_producer(producers[i]);
        this.subscribers[{pl.list[j], producers[i]}] = subscriber;
      end
    end
  end
endfunction: build_phase

/// Method for adding a uvm_sequence_item to a given queue for a given producer.
/// The method will check if the queue and producer exists before adding it to the queue.
/// 
/// The uvm_sequence_item will be wrapped by a cl_syoscb_item along with some META data
/// Thus, it is the cl_syoscb_item which will be added to the queue and not the uvm_sequence_item
/// directly.
///
/// This ensures that the scoreboard can easily be added to an existing testbench with already defined
/// sequence items etc.
function void cl_syoscb::add_item(string queue_name, string producer, uvm_sequence_item item);
  uvm_sequence_item item_clone;

  // Check queue
  if(!this.cfg.exist_queue(queue_name)) begin
    `uvm_fatal("CFG_ERROR", $sformatf("[%s]: Queue: %0s is not found", this.cfg.get_scb_name(), queue_name));
  end

  // Check producer
  if(!this.cfg.exist_producer(producer)) begin
    `uvm_fatal("CFG_ERROR", $sformatf("[%s]: Producer: %0s is not found", this.cfg.get_scb_name(), producer));
  end

  // Clone the item if not disabled
  // Clone the item in order to isolate the UVM scb from the rest of the TB
  if(this.cfg.get_disable_clone() == 1'b0) begin
    if(!$cast(item_clone, item.clone())) begin
      `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: Unable to cast cloned item to uvm_sequence_item", this.cfg.get_scb_name()));
    end
  end else begin
    item_clone = item;
  end

  // Add the uvm_sequence_item to the queue for the given producer
  begin
    cl_syoscb_queue queue;

    queue = this.cfg.get_queue(queue_name);
   
    if(queue == null) begin
      `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: Queue: %s not found by add_item method", this.cfg.get_scb_name(), queue_name));
    end

    if(!queue.add_item(producer, item_clone)) begin
      `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: Unable to add item to queue: %s", this.cfg.get_scb_name(), queue_name));
    end
  end

  `uvm_info("DEBUG", $sformatf("[%s]: Trigger compare by queue: %s, producer: %s", this.cfg.get_scb_name(), queue_name, producer), UVM_FULL);

  // Invoke the compare algorithm
  void'(this.compare());
endfunction: add_item

/// Invokes the compare strategy
function void cl_syoscb::compare();
  this.compare_strategy.compare();
endfunction: compare

/// Returns a UVM subscriber for a given combination of queue and producer
/// The returned UVM subscriber can then be connected to a UVM monitor or similar
/// which produces transactions which should be scoreboarded.
function cl_syoscb_subscriber cl_syoscb::get_subscriber(string queue_name, string producer);
  if(this.subscribers.exists({queue_name, producer})) begin
    return(this.subscribers[{queue_name, producer}]);
  end else begin
        `uvm_fatal("SUBSCRIBER_ERROR", $sformatf("[%s]: Unable to get subscriber for queue: %s and producer: %s", this.cfg.get_scb_name(), queue_name, producer));
        return(null);
  end
endfunction: get_subscriber

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.