hdk/common/verif/models/base/gen_buf_t.sv (212 lines of code) (raw):

// ============================================================================ // Amazon FPGA Hardware Development Kit // // Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. // // Licensed under the Amazon Software License (the "License"). You may not use // this file except in compliance with the License. A copy of the License is // located at // // http://aws.amazon.com/asl/ // // or in the "license" file accompanying this file. This file is distributed on // an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or // implied. See the License for the specific language governing permissions and // limitations under the License. // ============================================================================ //************************************************************************************* //------------------------------------------------------------------------------------- // Generic Buffer class. has data array, and methods to read/write to/from host memory, // and compare buffers. //------------------------------------------------------------------------------------- //************************************************************************************* `ifndef __DEFINED_GEN_BUF_T__ `define __DEFINED_GEN_BUF_T__ class gen_buf_t; logic[7:0] data[$]; bit print_ok_compare = 0; //Input size of buffer in bytes -- assume address of all f's is "null" function new (); endfunction //Initialization with incrementing data. Note this assumes empty array (queue), and adds entries to the array virtual function void init_inc(input[31:0] first_data, input int length = 4); bit[31:0] tmp_data; tmp_data = first_data; for (int i=0; i<length; i++) begin this.data.push_back(tmp_data[8*i[1:0]+:8]); if (i[1:0]==2'b11) tmp_data++; end endfunction //Initialization with constant. Note this assumes empty array (queue), and adds entries to the array virtual function void init_const(input[31:0] first_data, input int length = 4); for (int i=0; i<length; i++) begin this.data.push_back(first_data[8*i[1:0]+:8]); end endfunction //Initialization with random_data. Note this assumes empty array (queue), and adds entries to the array virtual function void init_rnd(input int length = 4); for (int i=0; i<length; i++) begin this.data.push_back($urandom()); end endfunction //Write with incrementing data. Note this uses existing entries in the queue/array // By default write the entire buffer virtual function void write_inc(input int start_addr=0, input[31:0] first_data=0, input int length = 32'hffffffff); bit[31:0] tmp_data; length = (length==32'hffffffff)? data.size(): length; tmp_data = first_data; for (int i=0; i<length; i++) begin if (i<data.size()) this.data[i] = tmp_data[8*i[1:0]+:8]; if (i[1:0]==2'b11) tmp_data++; end endfunction //Initialization with constant. Note this uses existing entries int the queue/array. // By default write the entire buffer virtual function void write_const(input int start_addr=0, input[31:0] first_data=0, input int length = 32'hffffffff); length = (length==32'hffffffff)? data.size(): length; for (int i=0; i<length; i++) begin if (i<data.size()) this.data[i] = first_data[8*i[1:0]+:8]; end endfunction //Initialization with random_data. Note this uses existing entries in the queue/array // By default write the entire buffer virtual function void write_rnd(input int length = 32'hffffffff); length = (length==32'hffffffff)? data.size(): length; for (int i=0; i<length; i++) begin if (i<data.size()) this.data[i] = $urandom(); end endfunction //Compare buffer virtual function bit compare(gen_buf_t compare_to, input int length=32'hffffffff); bit ret = 0; int cmp_length; logic[7:0] data_elem; logic[7:0] comp_data_elem; bit[31:0] tmp_data; bit[31:0] tmp_data_to; string tmp_s; //If length is not specified then use length of the buffer if (length==32'hffffffff) begin if (this.data.size() != compare_to.data.size()) begin $display($time,,,"***ERROR*** gen_buf_t compare length miscompare. this=%0d, compare_to=%0d", this.data.size(), compare_to.data.size()); end cmp_length = this.data.size(); end for (int i=0; i<cmp_length; i++) begin data_elem = this.data[i]; comp_data_elem = compare_to.data[i]; if (this.data.size()<=i) begin $display($time,,,"***ERROR*** gen_buf_t buffer too short, this.data.size()=0x%x, cmp_length=0x%x", this.data.size(), cmp_length); ret = 1; end else if (compare_to.data.size()<=i) begin $display($time,,,"***ERROR*** gen_buf_t.compare_to buffer too short, compare_to.data.size()=0x%x, cmp_length=0x%x", compare_to.data.size(), cmp_length); ret = 1; end else if (data_elem != comp_data_elem) begin $display($time,,,"***ERROR*** gen_buf_t.compare data mismatch address[0x%x]: buf_t=0x%x, compare_to=0x%x", i, this.data[i], compare_to.data[i]); ret = 1; end //For debug can print out OK compares else if (this.print_ok_compare) begin $display($time,,,"!!!COMPARE OK!!! gen_buf_t.compare address[0x%x]: buf_t=0x%x, compare_to=0x%x", i, this.data[i], compare_to.data[i]); end end //If got an error display entire packet if (ret) begin for (int i=0; i< (cmp_length/4 + |cmp_length[1:0]); i++) begin tmp_data = 0; tmp_data_to = 0; for (int b=0; b<4; b++) begin if ((i*4 + b) < cmp_length) begin tmp_data[b*8+:8] = this.data[i*4 + b]; tmp_data_to[b*8+:8] = compare_to.data[i*4 + b]; end end if (tmp_data != tmp_data_to) tmp_s = " ***MISCOMPARE***"; else tmp_s = ""; $display($time,,," addr[0x%4x]: 0x%8x 0x%8x %s", i*4, tmp_data, tmp_data_to, tmp_s); end end return ret; endfunction //Compare just a byte array queue (if dis-similar data type) virtual function bit compare_byte_array(logic[7:0] compare_to [$], input int length=32'hffffffff); bit ret = 0; int cmp_length; logic[7:0] data_elem; logic[7:0] comp_data_elem; //If length is not specified then use length of the buffer cmp_length = (length==32'hffffffff)? this.data.size(): length; for (int i=0; i<cmp_length; i++) begin data_elem = this.data[i]; comp_data_elem = compare_to[i]; if (this.data.size()<=i) begin $display($time,,,"***ERROR*** gen_buf_t buffer too short, this.data.size()=0x%x, cmp_length=0x%x", this.data.size(), cmp_length); ret = 1; end else if (compare_to.size()<=i) begin $display($time,,,"***ERROR*** gen_buf_t.compare_to buffer too short, compare_to.data.size()=0x%x, cmp_length=0x%x", compare_to.size(), cmp_length); ret = 1; end else if (data_elem != comp_data_elem) begin $display($time,,,"***ERROR*** gen_buf_t.compare data mismatch addres[0x%x]: buf_t=0x%x, compare_to=0x%x", i, this.data[i], compare_to[i]); ret = 1; end //For debug can print out OK compares else if (this.print_ok_compare) begin $display($time,,,"!!!COMPARE OK!!! gen_buf_t.compare addres[0x%x]: buf_t=0x%x, compare_to=0x%x", i, this.data[i], compare_to[i]); end end return ret; endfunction virtual function void display(input int length=32'hffffffff); logic[31:0] tmp_dw; int num_dw; int tmp_size; tmp_size = (length==32'hffffffff)? this.data.size(): length; num_dw = tmp_size/4; num_dw = ((tmp_size % 4)==0)? num_dw: num_dw + 1; $display("PktDisplay length=0x%x:", this.data.size()); for (int i=0; i<num_dw; i++) begin tmp_dw = 0; for (int j=0; j<4; j++) begin if (this.data.size() >= ((i*4)+j)) tmp_dw[j*8+:8] = this.data[i*4 + j]; end $display(" data[0x%4x] = 0x%8x", i*4, tmp_dw); end endfunction endclass `endif