📄 eth_frame.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.// -------------------------------------------------------------// `ifdef ETH_USE_COMPOSITION// Example 4-40class eth_vlan_data; rand bit [ 2:0] user_priority; rand bit cfi; rand bit [11:0] id;endclass: eth_vlan_data`endif// Example 4-14// Example 4-28// Example 4-32class eth_frame extends vmm_data; // Example 4-33 static vmm_log log = new("eth_frame", "class"); static eth_utils utils = new; // Example 4-36 vmm_data context_data; // Example 4-38 // Example 4-39 // A frame can either be tagged, untagged or be a control frame typedef enum {UNTAGGED, TAGGED, CONTROL} frame_formats_e; rand frame_formats_e format; rand bit [47:0] dst; rand bit [47:0] src;`ifdef ETH_USE_COMPOSITION // Example 4-40 rand eth_vlan_data vlan;`else rand bit [ 2:0] user_priority; // if TAGGED rand bit cfi; // if TAGGED rand bit [11:0] vlan_id; // if TAGGED`endif // Example 4-34 rand bit [15:0] len_typ; rand bit [15:0] opcode; // if CONTROL rand bit [15:0] pause_time; // if opcode == PAUSE rand int data_size; rand bit [ 7:0] data[]; // Example 4-37 rand bit [31:0] fcs; // // Opcodes // typedef enum [15:0] {PAUSE = 16'h0001} opcodes_e; // // Faclitate expressing constraints // // Example 4-42 rand int unsigned min_len; rand int unsigned max_len; // // Constraints to always generate a valid frame // constraint eth_frame_valid { min_len <= max_len; data.size() == data_size; } constraint valid_untagged_frame { if (format == UNTAGGED) { len_typ != 16'h8808; len_typ != 16'h8100; min_len == ((len_typ >= 'h0600) ? 46 : 0); max_len == 1500; } } constraint valid_tagged_frame { if (format == TAGGED) { len_typ != 16'h8808; min_len == ((len_typ >= 'h0600) ? 44 : 0); max_len == 1500; } } constraint valid_control_frame { if (format == CONTROL) { len_typ == 16'h8808; min_len == max_len; } } constraint valid_opcode { opcode == PAUSE; } constraint no_control_frames { format != CONTROL; } // Example 4-38 constraint valid_pause_frame { if (format == CONTROL && opcode == PAUSE) { dst == 48'h0180C2000001; max_len == 42; } } // Example 4-34 constraint valid_len_typ { (data.size() <= 1500 && len_typ == data.size()) || len_typ >= 16'h0600; } constraint limit_data_size { data.size() < 65535; } // Example 4-43 constraint interesting_data_size { data_size dist {min_len :/ 1, [min_len+1:max_len-1] :/ 1, max_len :/ 1}; } // Example 4-37 constraint valid_fcs { fcs == 32'h0000_0000; } // Example 4-47 constraint test_constraints1; constraint test_constraints2; constraint test_constraints3; `ifdef ETH_USE_COMPOSITION // Example 4-40 function void pre_randomize(); if (this.vlan == null) this.vlan = new; endfunction: pre_randomize`endif function void post_randomize();`ifdef ETH_USE_COMPOSITION if (format != TAGGED) this.vlan = null;`endif this.data = new [this.data_size] (this.data); if (format == CONTROL) begin foreach (data[i]) data[i] = 8'h00; end endfunction: post_randomize // // Methods // // Example 4-33 function new(); super.new(this.log); endfunction: new extern virtual function vmm_data allocate(); extern virtual function vmm_data copy(vmm_data to = null); extern virtual function bit compare(vmm_data to, output string diff, input int kind = -1); extern virtual function string psdisplay(string prefix = ""); extern virtual function bit is_valid(bit silent = 1, int kind = -1); extern virtual function int unsigned byte_size(int kind = -1); virtual function int unsigned max_byte_size(int kind = -1); max_byte_size = 1500; endfunction extern virtual function int unsigned byte_pack(ref logic [7:0] array[], input int unsigned offset = 0, input int kind = -1); extern virtual function int unsigned byte_unpack(const ref logic [7:0] array[], input int unsigned offset = 0, input int len = -1, input int kind = -1); extern virtual function bit [31:0] compute_fcs();endclass: eth_frame `vmm_channel(eth_frame)// Example 4-14`vmm_atomic_gen(eth_frame, "Ethernet Frame")`vmm_scenario_gen(eth_frame, "Ethernet Frame")function vmm_data eth_frame::allocate(); eth_frame i = new; allocate = i;endfunction: allocatefunction vmm_data eth_frame::copy(vmm_data to); eth_frame cpy; if (to != null) begin if (!$cast(cpy, to)) begin `vmm_error(this.log, "Cannot copy to non-eth_frame instance"); return null; end end else cpy = new; super.copy_data(cpy); cpy.format = this.format; cpy.dst = this.dst; cpy.src = this.src;`ifdef ETH_USE_COMPOSITION if (this.vlan != null) begin cpy.vlan = new; cpy.vlan.user_priority = this.vlan.user_priority; cpy.vlan.cfi = this.vlan.cfi; cpy.vlan.id = this.vlan.id; end`else cpy.user_priority = this.user_priority; cpy.cfi = this.cfi; cpy.vlan_id = this.vlan_id;`endif cpy.len_typ = this.len_typ; cpy.opcode = this.opcode; cpy.pause_time = this.pause_time; cpy.data = this.data; copy = cpy;endfunction: copyfunction bit eth_frame::compare(vmm_data to, output string diff, input int kind); eth_frame fr; int no_data = 0; compare = 0; if (to == null || !$cast(fr, to)) begin `vmm_error(this.log, "Cannot compare to non-eth_frame instance"); return 0; end if (fr.format !== this.format) begin $sformat(diff, "format (%0s !== %0s)", this.format.name(), fr.format.name()); return 0; end if (fr.dst !== this.dst) begin $sformat(diff, "dst (48'h%h !== 48'h%h)", this.dst, fr.dst); return 0; end if (fr.src !== this.src) begin $sformat(diff, "src (48'h%h !== 48'h%h)", this.src, fr.src); return 0; end if (fr.len_typ !== this.len_typ) begin if (this.len_typ >= 16'h0600) begin $sformat(diff, "len_typ (16'h%h !== 16'h%h)", this.len_typ, fr.len_typ); end else begin $sformat(diff, "len_typ (16'd%0d !== 16'd%0d)", this.len_typ, fr.len_typ); end return 0; end if (this.format == eth_frame::TAGGED) begin`ifdef ETH_USE_COMPOSITION if (fr.vlan == null) begin diff = "No vlan data"; return 0; end if (fr.vlan.user_priority !== this.vlan.user_priority) begin $sformat(diff, "user_priority (3'd%0d !== 3'd%0d)", this.vlan.user_priority, fr.vlan.user_priority); return 0; end if (fr.vlan.cfi !== this.vlan.cfi) begin $sformat(diff, "cfi (1'b%b !== 1'b%b)", this.vlan.cfi, fr.vlan.cfi); return 0; end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -