⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eth_frame_scenario_gen.sv

📁 VMM 文档加源码, synopsys公司很好的验证资料
💻 SV
字号:
// // -------------------------------------------------------------//    Copyright 2004-2008 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.// -------------------------------------------------------------// //// This generator is similar to the one produced by// the `vmm_scenario_gen() macro.//// Example 5-28class eth_frame_sequence extends vmm_data;   static vmm_log log;   int next_sequence_kind = 0;   int max_length = 1;   local string  sequence_names[*];   int unsigned stream_id;   int unsigned sequence_id;   // Example 5-29   rand int unsigned sequence_kind;   rand int unsigned length;   eth_frame using;   // Example 5-28   rand eth_frame items[];   constraint eth_frame_sequence_constr_basic {      sequence_kind >= 0;      sequence_kind < next_sequence_kind;      length >= 0;      length <= max_length;`ifndef NO_SIZE_IN_CONSTRAINT      items.size() == length;`endif      solve sequence_kind before length;   }   function new();      super.new(this.log);      if (this.log == null) begin         this.log = new({"Ethernet Frame Sequence"}, "Class");         this.notify.log = this.log;      end      this.using = new;   endfunction: new   virtual function void display(string prefix = "");      $display(this.psdisplay(prefix));   endfunction: display   virtual function string psdisplay(string prefix = "");      int i;      $sformat(psdisplay, "%sSequence \"%s\": kind=%0d, length=%0d (max=%0d)\n",               prefix, this.sequence_name(this.sequence_kind), this.sequence_kind, this.length, this.max_length);      foreach (this.items[i]) begin          psdisplay = {psdisplay, this.items[i].psdisplay($psprintf("%s   Item #%0d: ", prefix, i))};      end   endfunction: psdisplay   function int unsigned define_sequence(string name,                                         int    max_len);      define_sequence = this.next_sequence_kind++;      this.sequence_names[define_sequence] = name;      if (max_len > this.max_length) this.max_length = max_len;   endfunction: define_sequence   function void redefine_sequence(int unsigned sequence_kind,                                   string       name,                                   int          max_len);      this.sequence_names[sequence_kind] = name;      if (max_len > this.max_length) this.max_length = max_len;   endfunction: redefine_sequence   function string sequence_name(int sequence_kind);      if (!this.sequence_names.exists(sequence_kind)) begin         `vmm_error(this.log, $psprintf("Cannot find sequence name: undefined sequence kind %0d",                                        sequence_kind));         return "?";      end      sequence_name = this.sequence_names[sequence_kind];   endfunction: sequence_name   function void allocate_sequence(eth_frame using = null);      this.items = new [this.max_length];      foreach (this.items[i]) begin         if (using == null) $cast(this.items[i], this.using.copy());         else $cast(this.items[i], using.copy());      end   endfunction: allocate_sequence   function void fill_sequence(eth_frame using = null);      int i;      this.items = new [this.max_length] (this.items);      foreach (this.items[i]) begin         if (this.items[i] != null) continue;         if (using == null) $cast(this.items[i], this.using.copy());         else $cast(this.items[i], using.copy());      end   endfunction: fill_sequence   function void pre_randomize();      if (this.items.size() < this.max_length)         this.fill_sequence();   endfunction: pre_randomize   virtual task apply(eth_frame_channel channel,                      ref int           n_insts);      int i;      for (i = 0; i < this.length; i++) begin         eth_frame item;         $cast(item, this.items[i].copy());         channel.put(item);      end      n_insts = this.length;   endtask: applyendclassclass eth_frame_atomic_sequence extends eth_frame_sequence;   int unsigned ATOMIC;   constraint atomic_sequence {      if (sequence_kind == ATOMIC) {         length == 1;      }   }   function new();      super.new();      this.ATOMIC = this.define_sequence("Atomic", 1);      this.sequence_kind   = this.ATOMIC;      this.length = 1;   endfunction: new   virtual function string psdisplay(string prefix = "");      psdisplay = super.psdisplay(prefix);   endfunction:psdisplay   virtual task apply(eth_frame_channel channel,                      ref int           n_insts);      super.apply(channel, n_insts);   endtask: applyendclasstypedef class eth_frame_sequence_gen;class eth_frame_sequence_gen_callbacks extends vmm_xactor_callbacks;   virtual task post_sequence_gen(eth_frame_sequence_gen gen,                                  eth_frame_sequence     seq,                                  ref bit                dropped);   endtaskendclass// Example 5-28class eth_frame_sequence_gen extends vmm_xactor;   local int unsigned sequence_count;   local int unsigned inst_count;   int unsigned stop_after_n_insts;   int unsigned stop_after_n_sequences;   typedef enum int {GENERATED, DONE} symbols_e;   eth_frame_channel out_chan;   // Example 5-28   eth_frame_sequence randomized_sequence;   function new(string            instance,                int               stream_id = -1,                eth_frame_channel out_chan  = null);      super.new("Ethernet Frame Sequence Generator", instance, stream_id);      if (out_chan == null) begin         out_chan = new("Ethernet Frame Sequence Generator output channel",                        instance);      end      this.out_chan = out_chan;      this.log.is_above(this.out_chan.log);      this.inst_count = 0;      this.sequence_count = 0;      this.stop_after_n_insts     = 0;      this.stop_after_n_sequences = 0;      begin         eth_frame_atomic_sequence sc = new;         this.randomized_sequence = sc;      end      this.notify.configure(GENERATED);      this.notify.configure(DONE, vmm_notify::ON_OFF);   endfunction: new   virtual task inject_obj(eth_frame obj);      eth_frame_atomic_sequence seq = new;      seq.items    = new [1];      seq.items[0] = obj;      this.inject(seq);   endtask: inject_obj   virtual task inject(eth_frame_sequence seq);      bit drop = 0;      this.wait_if_stopped();      seq.stream_id   = this.stream_id;      seq.sequence_id = this.sequence_count;      foreach (seq.items[i]) begin         seq.items[i].stream_id   = seq.stream_id;         seq.items[i].scenario_id = seq.sequence_id;         seq.items[i].data_id     = i;      end      `vmm_callback(eth_frame_sequence_gen_callbacks,                    post_sequence_gen(this, seq, drop));      if (!drop) begin         int n_insts = 0;         this.sequence_count++;         this.notify.indicate(GENERATED, seq);         seq.apply(this.out_chan, n_insts);         this.inst_count += n_insts;      end   endtask: inject   virtual function void reset_xactor(reset_e rst_type = SOFT_RST);      super.reset_xactor(rst_type);      this.sequence_count = 0;      this.inst_count     = 0;      this.out_chan.flush();      if (rst_type >= FIRM_RST) begin         this.notify.reset( , vmm_notify::HARD);      end      if (rst_type >= HARD_RST) begin         eth_frame_atomic_sequence sc = new;         this.stop_after_n_insts     = 0;         this.stop_after_n_sequences = 0;         this.randomized_sequence = sc;      end   endfunction: reset_xactor   // Example 5-28   virtual protected task main();      fork         super.main();      join_none      while ((this.stop_after_n_insts <= 0              || this.inst_count < this.stop_after_n_insts)             && (this.stop_after_n_sequences <= 0                 || this.sequence_count < this.stop_after_n_sequences)) begin         this.wait_if_stopped();         // Example 5-28         if (!this.randomized_sequence.randomize()) begin            `vmm_error(this.log, "Cannot randomize sequence descriptor");            continue;         end         this.inject(this.randomized_sequence);      end      this.notify.indicate(DONE);      this.notify.indicate(vmm_xactor::XACTOR_STOPPED);      this.notify.indicate(vmm_xactor::XACTOR_IDLE);      this.notify.reset(vmm_xactor::XACTOR_BUSY);      this.sequence_count++;   endtask: main endclass

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -