00001 /// Top level class implementing the root of the SyoSil UVM scoreboard 00002 class cl_syoscb extends uvm_scoreboard; 00003 //------------------------------------- 00004 // Non randomizable variables 00005 //------------------------------------- 00006 /// Handle to the global UVM scoreboard configuration 00007 local cl_syoscb_cfg cfg; 00008 00009 /// Array holding handles to all queues 00010 local cl_syoscb_queue queues[]; 00011 00012 // Handle to the compare strategy 00013 local cl_syoscb_compare compare_strategy; 00014 00015 // Assoc array holding each uvm_subscriber 00016 local cl_syoscb_subscriber subscribers[string]; 00017 00018 //------------------------------------- 00019 // UVM Macros 00020 //------------------------------------- 00021 `uvm_component_utils_begin(cl_syoscb) 00022 `uvm_field_object(cfg, UVM_DEFAULT) 00023 `uvm_field_array_object(queues, UVM_DEFAULT) 00024 `uvm_field_object(compare_strategy, UVM_DEFAULT) 00025 `uvm_field_aa_object_string(subscribers, UVM_DEFAULT) 00026 `uvm_component_utils_end 00027 00028 //------------------------------------- 00029 // Constructor 00030 //------------------------------------- 00031 extern function new(string name = "cl_syoscb", uvm_component parent = null); 00032 00033 //------------------------------------- 00034 // UVM Phase methods 00035 //------------------------------------- 00036 extern function void build_phase(uvm_phase phase); 00037 00038 //------------------------------------- 00039 // Function based API 00040 //------------------------------------- 00041 extern function void add_item(string queue_name, string producer, uvm_sequence_item item); 00042 extern function void compare(); 00043 00044 //------------------------------------- 00045 // Transaction based API 00046 //------------------------------------- 00047 extern function cl_syoscb_subscriber get_subscriber(string queue_name, string producer); 00048 endclass: cl_syoscb 00049 00050 function cl_syoscb::new(string name = "cl_syoscb", uvm_component parent = null); 00051 super.new(name, parent); 00052 endfunction : new 00053 00054 /// The build_phase gets the scoreboard configuration and forwards it to the child components (cl_syoscb_queue 00055 /// and cl_syoscb_compare). Additionally, it creates all of the queues defined in the configuration object. Finally, 00056 /// it also creates the compare strategy via a factory create call. 00057 function void cl_syoscb::build_phase(uvm_phase phase); 00058 if (!uvm_config_db #(cl_syoscb_cfg)::get(this, "", "cfg", this.cfg)) begin 00059 // *NOTE*: If no cfg object is given then no scb name is available 00060 // Thus, no scb name is printed here 00061 `uvm_fatal("CFG_ERROR", "Configuration object not passed.") 00062 end 00063 00064 // Set the default SCB name if not specified explicitly 00065 if(this.cfg.get_scb_name() == "") begin 00066 this.cfg.set_scb_name(this.get_name()); 00067 end 00068 00069 // Create list of queues 00070 this.queues = new[this.cfg.size_queues()]; 00071 00072 // Create the queues as defined in the configuration 00073 begin 00074 string queue_names[]; 00075 00076 // Get teh list of queue names 00077 this.cfg.get_queues(queue_names); 00078 00079 foreach(queue_names[i]) begin 00080 this.queues[i] = cl_syoscb_queue::type_id::create(queue_names[i], this); 00081 this.cfg.set_queue(queue_names[i], this.queues[i]); 00082 00083 // Forward the configuration to the queue 00084 uvm_config_db #(cl_syoscb_cfg)::set(this, queue_names[i], "cfg", this.cfg); 00085 end 00086 end 00087 00088 // Forward the configuration to the compare_strategy 00089 uvm_config_db #(cl_syoscb_cfg)::set(this, "compare_strategy", "cfg", this.cfg); 00090 00091 // Create the compare strategy 00092 this.compare_strategy = cl_syoscb_compare::type_id::create(.name("compare_strategy"), .parent(this)); 00093 00094 begin 00095 cl_syoscb_report_catcher catcher = new(); 00096 uvm_report_cb::add(null, catcher); 00097 end 00098 00099 begin 00100 string producers[]; 00101 00102 this.cfg.get_producers(producers); 00103 00104 foreach(producers[i]) begin 00105 cl_syoscb_cfg_pl pl = this.cfg.get_producer(producers[i]); 00106 00107 foreach(pl.list[j]) begin 00108 cl_syoscb_subscriber subscriber; 00109 00110 subscriber = cl_syoscb_subscriber::type_id::create({producers[i], "_", pl.list[j], "_subscr"}, this); 00111 subscriber.set_queue_name(pl.list[j]); 00112 subscriber.set_producer(producers[i]); 00113 this.subscribers[{pl.list[j], producers[i]}] = subscriber; 00114 end 00115 end 00116 end 00117 endfunction: build_phase 00118 00119 /// Method for adding a uvm_sequence_item to a given queue for a given producer. 00120 /// The method will check if the queue and producer exists before adding it to the queue. 00121 /// 00122 /// The uvm_sequence_item will be wrapped by a cl_syoscb_item along with some META data 00123 /// Thus, it is the cl_syoscb_item which will be added to the queue and not the uvm_sequence_item 00124 /// directly. 00125 /// 00126 /// This ensures that the scoreboard can easily be added to an existing testbench with already defined 00127 /// sequence items etc. 00128 function void cl_syoscb::add_item(string queue_name, string producer, uvm_sequence_item item); 00129 uvm_sequence_item item_clone; 00130 00131 // Check queue 00132 if(!this.cfg.exist_queue(queue_name)) begin 00133 `uvm_fatal("CFG_ERROR", $sformatf("[%s]: Queue: %0s is not found", this.cfg.get_scb_name(), queue_name)); 00134 end 00135 00136 // Check producer 00137 if(!this.cfg.exist_producer(producer)) begin 00138 `uvm_fatal("CFG_ERROR", $sformatf("[%s]: Producer: %0s is not found", this.cfg.get_scb_name(), producer)); 00139 end 00140 00141 // Clone the item if not disabled 00142 // Clone the item in order to isolate the UVM scb from the rest of the TB 00143 if(this.cfg.get_disable_clone() == 1'b0) begin 00144 if(!$cast(item_clone, item.clone())) begin 00145 `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: Unable to cast cloned item to uvm_sequence_item", this.cfg.get_scb_name())); 00146 end 00147 end else begin 00148 item_clone = item; 00149 end 00150 00151 // Add the uvm_sequence_item to the queue for the given producer 00152 begin 00153 cl_syoscb_queue queue; 00154 00155 queue = this.cfg.get_queue(queue_name); 00156 00157 if(queue == null) begin 00158 `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: Queue: %s not found by add_item method", this.cfg.get_scb_name(), queue_name)); 00159 end 00160 00161 if(!queue.add_item(producer, item_clone)) begin 00162 `uvm_fatal("QUEUE_ERROR", $sformatf("[%s]: Unable to add item to queue: %s", this.cfg.get_scb_name(), queue_name)); 00163 end 00164 end 00165 00166 `uvm_info("DEBUG", $sformatf("[%s]: Trigger compare by queue: %s, producer: %s", this.cfg.get_scb_name(), queue_name, producer), UVM_FULL); 00167 00168 // Invoke the compare algorithm 00169 void'(this.compare()); 00170 endfunction: add_item 00171 00172 /// Invokes the compare strategy 00173 function void cl_syoscb::compare(); 00174 this.compare_strategy.compare(); 00175 endfunction: compare 00176 00177 /// Returns a UVM subscriber for a given combination of queue and producer 00178 /// The returned UVM subscriber can then be connected to a UVM monitor or similar 00179 /// which produces transactions which should be scoreboarded. 00180 function cl_syoscb_subscriber cl_syoscb::get_subscriber(string queue_name, string producer); 00181 if(this.subscribers.exists({queue_name, producer})) begin 00182 return(this.subscribers[{queue_name, producer}]); 00183 end else begin 00184 `uvm_fatal("SUBSCRIBER_ERROR", $sformatf("[%s]: Unable to get subscriber for queue: %s and producer: %s", this.cfg.get_scb_name(), queue_name, producer)); 00185 return(null); 00186 end 00187 endfunction: get_subscriber
|
Project: SyoSil ApS UVM Scoreboard, Revision: 1.0.2.5 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. |
![]() Doxygen Version: 1.6.1 IDV SV Filter Version: 2.6.2 Sat Nov 28 05:41:54 2015 |