VMM OpenSource - sv/std_lib/vmm_test.sv

sv/std_lib/vmm_test.sv expanded source

00001 //
00002 // -------------------------------------------------------------
00003 //    Copyright 2004-2008 Synopsys, Inc.
00004 //    All Rights Reserved Worldwide
00005 //
00006 //    Licensed under the Apache License, Version 2.0 (the
00007 //    "License"); you may not use this file except in
00008 //    compliance with the License.  You may obtain a copy of
00009 //    the License at
00010 //
00011 //        http://www.apache.org/licenses/LICENSE-2.0
00012 //
00013 //    Unless required by applicable law or agreed to in
00014 //    writing, software distributed under the License is
00015 //    distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
00016 //    CONDITIONS OF ANY KIND, either express or implied.  See
00017 //    the License for the specific language governing
00018 //    permissions and limitations under the License.
00019 // -------------------------------------------------------------
00020 //
00021 
00022 
00023 class vmm_test_registry;
00024    static local vmm_opts _vmm_opts = new();
00025 
00026    local static vmm_test registry[string];
00027    local static vmm_log log = new("vmm_test_registry", "class");
00028    local static int width = 1;
00029 
00030    extern `VMM_STATIC_M task run(vmm_env env);
00031    extern `VMM_STATIC_M function void list();
00032 
00033    extern /*local*/ `VMM_STATIC_M function void Xregister_testX(vmm_test tst);
00034    extern local `VMM_STATIC_M function void display_known_tests(ref string msg[$],
00035                                                                 input bit fatal);
00036 endclass
00037 
00038 
00039 function vmm_test::new(string name,
00040                        string doc = "");
00041    this.log = new("Testcase", name);
00042    this.doc = doc;
00043    this.registry.Xregister_testX(this);
00044 endfunction
00045 
00046 
00047 function void vmm_test::Xset_log_instanceX(string inst);
00048    this.log.set_instance(inst);
00049 endfunction
00050 
00051 
00052 function string vmm_test::get_name();
00053    return this.log.get_instance();
00054 endfunction
00055 
00056 
00057 function string vmm_test::get_doc();
00058    return this.doc;
00059 endfunction
00060 
00061 
00062 task vmm_test::run(vmm_env env);
00063    env.run();
00064 endtask
00065 
00066 
00067 function void vmm_test_registry::Xregister_testX(vmm_test tst);
00068    string name;
00069 
00070    if (tst == null) begin
00071       `vmm_error(log, "Attemtping to register NULL test.");
00072       return;
00073    end
00074 
00075    name = tst.get_name();
00076 
00077    if (registry.exists(name)) begin
00078       `vmm_error(log, `vmm_sformatf("Attempting to register test \"%s\" more than once.",
00079                                     name));
00080       return;
00081    end
00082 
00083    registry[name] = tst;
00084 
00085    if (name.len() > width) width = name.len();
00086 endfunction
00087 
00088 
00089 task vmm_test_registry::run(vmm_env env);
00090    string   testname;
00091    vmm_test tst = null;
00092    vmm_test one_tst = null;
00093   
00094    if (registry.num() == 1) begin
00095       void'(registry.first(testname));
00096       one_tst = registry[testname];
00097    end
00098 
00099    if (!registry.exists("Default")) begin
00100       // Create a default testcase and run it
00101       tst = new("Default", "Default testcase that simply calls env::run()");
00102    end
00103 
00104    if (_vmm_opts.get_bit("test_help", "List available testcases")) begin
00105       list();
00106       $finish();
00107    end
00108 
00109    testname = _vmm_opts.get_string("test", ,
00110                                    "Name of testcase to run");
00111 
00112    // If no tests were specified but only one test is known, run it
00113    if (testname == "") begin
00114       string str;
00115 
00116       // If there was only one user-defined tests, use it
00117       if (one_tst != null) begin
00118          tst = one_tst;
00119          testname = tst.get_name();
00120       end
00121       // If there is only the default test, use it
00122       else if (registry.num() == 1) begin
00123          void'(registry.first(testname));
00124          tst = registry[testname];
00125       end
00126       // Don't known which test to use!
00127       else begin
00128          string msg[$];
00129 
00130          msg.push_back("No test was selected at runtime using +vmm_test=<test>.");
00131          msg.push_back("Available tests are:");
00132          display_known_tests(msg, 1);
00133          return;
00134       end
00135    end
00136    else begin
00137       if (!registry.exists(testname)) begin
00138          string msg[$];
00139          string str;
00140 
00141          $sformat(str, "Unknown test name \"%s\" specified.", testname);
00142          msg.push_back(str);
00143          display_known_tests(msg, 1);
00144          return;
00145       end
00146       tst = registry[testname];
00147    end
00148 
00149    `vmm_note(log, `vmm_sformatf("Running test \"%s\"...", testname));
00150    tst.run(env);
00151 endtask
00152 
00153 
00154 function void vmm_test_registry::list();
00155    string msg[$];
00156    string str;
00157 
00158    msg.push_back("Available tests are:");
00159    msg.push_back(str);
00160    display_known_tests(msg, 0);
00161 endfunction
00162 
00163 
00164 function void vmm_test_registry::display_known_tests(ref string msg[$],
00165                                                      input bit fatal);
00166    bit [12:0] n = 0;
00167    string     str;
00168    static string spaces = "                                            ";
00169 
00170    n = 0;
00171    foreach (registry[name]) begin
00172       string testname = name;
00173       $sformat(str, "%d) %s%s : %s", n++, testname,
00174                spaces.substr(0, width-testname.len()-1),
00175                registry[name].get_doc());
00176       msg.push_back(str);
00177    end
00178    if ((fatal && log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) ||
00179        (!fatal && log.start_msg(vmm_log::NOTE_TYP, vmm_log::NORMAL_SEV))) begin
00180       foreach (msg[i]) void'(log.text(msg[i]));
00181       log.end_msg();
00182    end
00183 endfunction