Verification Engineerの戯言
vmm_vxc_managerクラスのINTERRUPTコマンドを解釈するtry_interrupt関数を見てみましょう!
基本的には、try_action関数と同じです。
また、この部分は、`vmm_str_matchマクロを使って解釈しています。
基本的には、try_action関数と同じです。
function bit vmm_xvc_manager::try_interrupt(); // 途中、略 //parse cmd and extract information. //syntax is of the form: // I[NTERRUPT] [ONESHOT] <instance> <action> \ // [W[AIT] wait_for] \ // [E[VENT] event [event]] arg_no = 1; if (this.argv[arg_no].tolower() == "oneshot") begin is_oneshot = 1; arg_no++; end else begin is_oneshot = 0; end inst = this.argv[arg_no++]; action_str = this.argv[arg_no++]; while (1) begin string tmpstr; //if there are args still left over.. if (arg_no >= this.argv.size()) break; tmpstr = this.argv[arg_no].tolower; if(`vmm_str_match(tmpstr, "^(w|wait)")) begin arg_no++; //ToDo: error if no wait argument wait_for_ev = this.argv[arg_no++]; continue; end tmpstr = this.argv[arg_no].tolower; if (`vmm_str_match(tmpstr, "^(e|event)")) begin arg_no++; //ToDo: error if dont have atleast 1 arg while (`vmm_str_match(this.argv[arg_no], "^[0-9.]*$")) begin emit_ev_list.push_back(this.argv[arg_no]); arg_no++; if (arg_no >= this.argv.size()) break; end end end前半は構文の解釈部です。オプションのW[AIT]とE[MIT]は、この順番でないといけません。
また、この部分は、`vmm_str_matchマクロを使って解釈しています。
//Iterate over xactor instances begin xvc_xactor xvc; xvc_action action; this.for_reset(inst); xvc = this.for_each(); if (xvc == null) begin `vmm_error(this.log, $psprintf("%s, line %0d: No such XVC %s", this.testfile, this.linec, inst) ); return 1; endこでは、インスタンス(vxc)が存在するかどうかをチェックします。
// Actions can only apply to one XVC if (this.for_each() != null) begin `vmm_error(this.log, $psprintf("%s, line %0d: Action matches multiple XVCs %s", this.testfile, this.linec, inst) ); return 1; endここでは、アクションが特定のインスタンス(xvc)にだけのモノかをチェックします。
//There must be a current scenario for an action/interrupt if (this.current_sc == null) begin `vmm_error(this.log, $psprintf("%s, line %0d: Action not preceded by scenario", this.testfile, this.linec) ); return 1; endここでは、アクションがシナリオコマンドの後になっているかどうかをチェックします。
//Split up string , remove extra white spaces // and pass it as a argv array to the xvc.parse() begin string action_str_args[]; this.split(action_str, action_str_args); action = xvc.parse(action_str_args); if (action == null) return 1; endアクション部の文字列を分割、解析し、アクション部を取り出します。
//create the action and put it in the Q. begin vmm_xvc_action_block act_b = new; act_b.xvc_mgr = this; act_b.descr = action_str; act_b.action = action; act_b.xvc = xvc; act_b.sc = this.current_sc; act_b.is_interrupt = 1; act_b.is_interrupt_oneshot = is_oneshot; act_b.set_wait(wait_for_ev); act_b.set_emit(emit_ev_list); this.current_sc.actionQ.push_back(act_b); endこの部分でやっとアクションをactionQに登録します。
`ifdef VMM_DETAILED_MSGS if (this.log.start_msg(vmm_log::INTERNAL_TYP , vmm_log::DEBUG_SEV )) begin void'(this.log.text( $psprintf("%s, line %0d: Adding interrupt action %s to scenario %s...", this.testfile, this.linec, action_str, this.current_sc.name))); this.log.end_msg(); end `endif end endfunction: try_interrupt
検証、Verification、SystemVerilog、VMM、Verifica