fnob_common.sv (248 lines of code) (raw):

//################################################################################### // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. // The following information is considered proprietary and confidential to Facebook, // and may not be disclosed to any third party nor be used for any purpose other // than to full fill service obligations to Facebook //################################################################################### `ifndef __FNOB_COMMON_SV__ `define __FNOB_COMMON_SV__ typedef enum{ FNOB_NORM, FNOB_INV_NORM, FNOB_UNIF, FNOB_C_UNIF, FNOB_CONST, FNOB_PATN, FNOB_C_PATN, FNOB_IN_LIST, FNOB_INTVL, FNOB_DIST, FNOB_LOG, FNOB_SFS, FNOB_FSF, FNOB_PROF, FNOB_MULTI } FNOB_TYPE; typedef class fnob_rand; typedef class fnob_rand_norm; typedef class fnob_rand_inv_norm; typedef class fnob_rand_unif; typedef class fnob_randc_unif; typedef class fnob_rand_profile; typedef class fnob_rand_const; typedef class fnob_rand_pattern; typedef class fnob_randc_pattern; typedef class fnob_rand_inside_list; typedef class fnob_rand_intvl; typedef class fnob_rand_dist; typedef class fnob_rand_log; typedef class fnob_rand_sfs; typedef class fnob_rand_multi; class fnob_common#(type T=bit[63:0]) extends uvm_object; //fnob pools: used to check naming conflict or wrong spelling local static bit m_fnob_pool[string]; //-------------------------------------------------------------------------------- static function void fnob_name_add(string fnob_name); //check exist or not if(m_fnob_pool.exists(fnob_name)) `uvm_fatal("FNOB", $sformatf("fnob %s already exists", fnob_name)) else m_fnob_pool[fnob_name] = 1; endfunction: fnob_name_add //-------------------------------------------------------------------------------- static function void fnob_name_chk(string fnob_name); //check exist or not if(!m_fnob_pool.exists(fnob_name)) `uvm_fatal("FNOB", $sformatf("no fnob %s found, please check cfg_db override", fnob_name)) endfunction: fnob_name_chk //-------------------------------------------------------------------------------- static function void fnob_name_print(); //check exist or not foreach(m_fnob_pool[i]) `uvm_info("FNOB", $sformatf("fnob_pool %s", i), UVM_LOW) endfunction: fnob_name_print //-------------------------------------------------------------------------------- static function fnob_rand#(T) param_2_rand(string fnob_rand_name, FNOB_TYPE fnob_type, T params[string][$]); `uvm_info("param_2_rand", $psprintf("fnob_type=%s params=%p", fnob_type.name(), params), UVM_MEDIUM) case (fnob_type) FNOB_NORM: begin param_2_rand = fnob_rand_norm#(T)::init(fnob_rand_name, params["val"]);end FNOB_INV_NORM:begin param_2_rand = fnob_rand_inv_norm#(T)::init(fnob_rand_name, params["val"]);end FNOB_UNIF: begin param_2_rand = fnob_rand_unif#(T)::init(fnob_rand_name, params["val"]);end FNOB_C_UNIF: begin param_2_rand = fnob_randc_unif#(T)::init(fnob_rand_name, params["val"]);end FNOB_CONST: begin param_2_rand = fnob_rand_const#(T)::init(fnob_rand_name, params["val"]);end FNOB_PATN: begin param_2_rand = fnob_rand_pattern#(T)::init(fnob_rand_name, params["val"]);end FNOB_C_PATN: begin param_2_rand = fnob_randc_pattern#(T)::init(fnob_rand_name, params["val"]);end FNOB_IN_LIST: begin param_2_rand = fnob_rand_inside_list#(T)::init(fnob_rand_name, params["val"]);end FNOB_INTVL: begin param_2_rand = fnob_rand_intvl#(T)::init(fnob_rand_name, params["val"]);end FNOB_DIST: begin param_2_rand = fnob_rand_dist#(T)::init(fnob_rand_name, params);end FNOB_LOG: begin param_2_rand = fnob_rand_log#(T)::init(fnob_rand_name, params["val"]);end FNOB_SFS: begin param_2_rand = fnob_rand_sfs#(T)::init(fnob_rand_name, params, .is_sfs(1));end FNOB_FSF: begin param_2_rand = fnob_rand_sfs#(T)::init(fnob_rand_name, params, .is_sfs(0));end FNOB_PROF: begin param_2_rand = fnob_rand_profile#(T)::init(fnob_rand_name, params);end // FNOB_MULTI: return any type for multi is fine as it will be overriden FNOB_MULTI: begin param_2_rand = fnob_rand_unif#(T)::init(fnob_rand_name, params["val"]);end default: begin `uvm_fatal("param_2_rand", $psprintf("undefined fnob_type=%0s", fnob_type.name())) end endcase // case (fnob_type) endfunction // param_2_rand //-------------------------------------------------------------------------------- static function FNOB_TYPE s_2_type(string s); case(s) "norm": return FNOB_NORM; "inv_norm": return FNOB_INV_NORM; "unif": return FNOB_UNIF; "c_unif": return FNOB_C_UNIF; "constant": return FNOB_CONST; "pattern": return FNOB_PATN; "c_pattern": return FNOB_C_PATN; "in_list": return FNOB_IN_LIST; "intvl": return FNOB_INTVL; "dist": return FNOB_DIST; "log": return FNOB_LOG; "sfs": return FNOB_SFS; "fsf": return FNOB_FSF; "profile": return FNOB_PROF; "multi": return FNOB_MULTI; default: begin `uvm_fatal("s_2_type", $psprintf("illegal type=%s", s)) end endcase // case (s) endfunction // s_2_type //-------------------------------------------------------------------------------- static function void remove_space_in_str(ref string s, input string m=" "); string s_new = ""; for (int ii=0; ii<s.len(); ii++) begin if (string'(s[ii]) != m) begin //`uvm_info("remove_space_in_str", $psprintf("s=%s s_new=%s", s, s_new), UVM_MEDIUM) s_new = {s_new, s[ii]}; end end `uvm_info("remove_space_in_str", $psprintf("s=%s s_new=%s m=%s", s, s_new, m), UVM_MEDIUM) s = s_new; endfunction // remove_space_in_str //-------------------------------------------------------------------------------- static function void remove_partial_str(ref string s, input string m=" "); string s_new = ""; int jj = 0; for (int ii=0; ii<s.len(); ii++) begin if (string'(s[ii]) == string'(m[jj])) begin jj++; //`uvm_info("remove_space_in_str", $psprintf("s=%s s_new=%s", s, s_new), UVM_MEDIUM) end else begin s_new = {s_new, s[ii]}; end end `uvm_info("remove_partial_str", $psprintf("s=%s s_new=%s m=%s", s, s_new, m), UVM_MEDIUM) s = s_new; endfunction // remove_partial_str //-------------------------------------------------------------------------------- static function T s_2_val(string s); fnob_common#(T)::remove_space_in_str(s); // hex: 'h, 0x, 0X if (((s[0] == "'") && (s[1] == "h")) || ((s[0] == "0") && ((s[1] == "x") || (s[1] == "X")))) begin bit [7:0] s_1; bit [3:0] v_1; int shift = 0; for (int ii=(s.len()-1); ii>=2; ii--) begin s_1 = s[ii]; if ((s_1 >= "0") && (s_1 <= "9")) begin v_1 = s_1 - "0"; end else if ((s_1 >= "a") && (s_1 <= "f")) begin v_1 = s_1 - "a" + 10; end else if ((s_1 >= "A") && (s_1 <= "F")) begin v_1 = s_1 - "A" + 10; end else begin `uvm_fatal("s_2_val", $psprintf("invalid hex value: s=%0s v_1=%0h", s, v_1)) end s_2_val |= v_1 << shift; //`uvm_info(get_name(), $psprintf("s[%0d]=%s=%0h s_1=%0h v_1=%0h s_2_val=%h", ii, s[ii], s[ii], s_1, v_1, s_2_val), UVM_MEDIUM) shift += 4; end end // binary: 'b else if ((s[0] == "'") && (s[1] == "b")) begin bit [7:0] s_1; bit [3:0] v_1; int shift = 0; for (int ii=(s.len()-1); ii>=2; ii--) begin s_1 = s[ii]; if ((s_1 >= "0") && (s_1 <= "1")) begin v_1 = s_1 - "0"; end else begin `uvm_fatal("s_2_val", $psprintf("invalid binary value: s=%0s v_1=%0b", s, v_1)) end s_2_val |= v_1 << shift; shift += 1; end end // decimal else begin return s.atoi(); end endfunction // s_2_val //-------------------------------------------------------------------------------- static function string qidx_2_qstr(int qidx); if (qidx == 0) begin return "val"; end else begin return "prob"; end endfunction // qidx_2_qstr //-------------------------------------------------------------------------------- static function void s_2_param(string s, ref FNOB_TYPE fnob_type, ref T params[string][$]); int qidx = 0; int idx = 0; int prev = idx; fnob_common#(T)::remove_space_in_str(s); // illegal exit if (s[0] == ":") begin `uvm_fatal("s_2_param", $psprintf("illegal cfgdb str=%s missing type, expected <type>:<val>", s)) end // get type while ((idx < s.len()) && (s[idx] != ":")) begin idx++; end fnob_type = fnob_common#(T)::s_2_type(s.substr(0, idx-1)); idx++; prev = idx; // get val while (idx < s.len()) begin if ((s[idx] == ":") || (s[idx] == "_")) begin //`uvm_info("s_2_param", $psprintf("%s", s.substr(prev, idx-1)), UVM_MEDIUM) params[fnob_common#(T)::qidx_2_qstr(qidx)].push_back(fnob_common#(T)::s_2_val(s.substr(prev, idx-1))); prev = idx + 1; if (s[idx] == "_") begin qidx++; end end idx++; end //`uvm_info("s_2_param", $psprintf("%s", s.substr(prev, idx-1)), UVM_MEDIUM) params[fnob_common#(T)::qidx_2_qstr(qidx)].push_back(fnob_common#(T)::s_2_val(s.substr(prev, idx-1))); // last one endfunction // s_2_params //-------------------------------------------------------------------------------- static function string get_next_frand(ref string s); int idx = 0; fnob_common#(T)::remove_space_in_str(s); if (s[0] != "(") begin `uvm_fatal("get_next_frand", $psprintf("multi_fnob string must start with ( s=%0s", s)) end while ((idx < s.len()) && (s[idx] != ")")) begin idx++; end get_next_frand = s.substr(1, idx-1); s = s.substr(idx+1, s.len()-1); `uvm_info("get_next_frand", $psprintf("get_next_frand=%s s=%0s", get_next_frand, s), UVM_MEDIUM) endfunction // get_next_frand endclass // fnob_common `endif