//
// -------------------------------------------------------------
//    Copyright 2004-2009 Synopsys, Inc.
//    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.
// -------------------------------------------------------------
//


//
// Redirect VMM messages to OVM with the following mapping
//
//   VMM FATAL   --> OVM FATAL/NONE
//   VMM ERROR   --> OVM ERROR/LOW
//   VMM WARNING --> OVM WARNING/MEDIUM
//   default     --> OVM INFO/MEDIUM
//     TRACE_SEV             /HIGH
//     DEBUG_SEV             /FULL
//     VERBOSE_SEV           /DEBUG
//


class avt_ovm_vmm_log_fmt extends vmm_log_format;

`ifdef OVM_ON_TOP
   static local avt_ovm_vmm_log_fmt auto_register = new();
`endif

   local ovm_report_server svr;
   local ovm_reporter client;
   local vmm_log log;

   function new();
      ovm_report_global_server gs = new;
      this.svr    = gs.get_server();
      this.client = new("VMM->OVM Report Client");
      this.log    = new("VMM->OVM", "Redirector");
      void'(this.log.set_format(this));
      // Make sure all messages are issed on the OVM side
      this.client.set_report_verbosity_level(32'h7FFF_FFFF);
      // Let OVM abort after too many errors
      this.log.stop_after_n_errors(0);
   endfunction


   virtual function string format_msg(string name,
                                      string inst,
                                      string msg_typ,
                                      string severity,
`ifdef VMM_LOG_FORMAT_FILE_LINE
                                      string fname,
                                      int    line,
`endif
                                      ref string lines[$]);
`ifndef VMM_LOG_FORMAT_FILE_LINE
      string fname = "";
      int    line  = 0;
`endif
      ovm_severity ovm_sev;
      int ovm_verb;
      string msg;

      ovm_sev  = OVM_INFO;
      ovm_verb = OVM_MEDIUM;

      if (severity == this.log.sev_image(vmm_log::FATAL_SEV))
         ovm_verb = OVM_NONE;
      else if (severity == this.log.sev_image(vmm_log::ERROR_SEV))
         ovm_verb = OVM_LOW;
      else if (severity == this.log.sev_image(vmm_log::TRACE_SEV))
         ovm_verb = OVM_HIGH;
      else if (severity == this.log.sev_image(vmm_log::DEBUG_SEV))
         ovm_sev = OVM_FULL;
      else if (severity == this.log.sev_image(vmm_log::VERBOSE_SEV))
         ovm_sev = OVM_DEBUG;

      if (msg_typ == this.log.typ_image(vmm_log::FAILURE_TYP)) begin
         case (ovm_verb)
            OVM_NONE:   ovm_sev = OVM_FATAL;
            OVM_LOW:    ovm_sev = OVM_ERROR;
            OVM_MEDIUM: ovm_sev = OVM_WARNING;
         endcase
      end

      if (lines.size() > 0) begin
         int i = 1;
         msg = lines[0];
         while (i < lines.size()) begin
            msg = {msg, "\n", lines[i]};
         end
      end

      this.svr.report(ovm_sev, name, inst, msg, ovm_verb,
                      fname, line, this.client);

      return "";
   endfunction: format_msg
   

   virtual function string continue_msg(string name,
                                        string inst,
                                        string msg_typ,
                                        string severity,
`ifdef VMM_LOG_FORMAT_FILE_LINE
                                        string fname,
                                        int    line,
`endif
                                        ref string lines[$]);
      return this.format_msg(name, inst, msg_typ, severity,
`ifdef VMM_LOG_FORMAT_FILE_LINE
                             fname, line,
`endif
                             lines);
   endfunction: continue_msg
endclass
