Tests: Add uvm_dpi

This commit is contained in:
Wilson Snyder 2025-08-02 13:50:16 -04:00
parent 473d54aa95
commit 12355270b3
17 changed files with 1665 additions and 0 deletions

View File

@ -27,6 +27,8 @@ for filename in files.split():
continue
if "include/gtkwave/" in filename: # Standard file - can't change it
continue
if "test_regress/t/uvm/dpi/" in filename: # Standard file - can't change it
continue
filename = os.path.join(root, filename)
if not os.path.exists(filename):
continue

View File

@ -45,6 +45,7 @@ EXEMPT_FILES_LIST = """
test_regress/t/t_incr_void.v
test_regress/t/tsub/t_flag_f_tsub.v
test_regress/t/tsub/t_flag_f_tsub_inc.v
test_regress/t/uvm/dpi
test_regress/t/uvm/uvm_pkg_all.svh
test_regress/t/uvm/uvm_pkg_todo.svh
verilator.pc.in

View File

@ -0,0 +1,37 @@
uvm_dpi_get_tool_name_c() = Verilator
uvm_dpi_get_tool_version_c() = 5.039 devel
= uvm_re
= uvm_hdl_check_path
= uvm_hdl_read simple variable
= uvm_hdl_read not found (bad)
===
UVM Report expected on next line:
UVM Report ../../t/uvm/dpi/uvm_hdl_verilator.c: 54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.__DEPOSIT_NOT_FOUND)
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
= uvm_hdl_deposit simple variable
= uvm_hdl_read single bit
= uvm_hdl_deposit single bit
= uvm_hdl_read multi-bit
= uvm_hdl_deposit multi-bit
= uvm_hdl_deposit bad ranges
===
UVM Report expected on next line:
UVM Report ../../t/uvm/dpi/uvm_hdl_verilator.c: 54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.exposed[10:3])
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
===
UVM Report expected on next line:
UVM Report ../../t/uvm/dpi/uvm_hdl_verilator.c: 54: UVM/DPI/HDL_SET set: unable to locate hdl path (t.exposed[99:15])
Either the name is incorrect, or you may not have PLI/ACC visibility to that name
= uvm_hdl_force
===
UVM Report expected on next line:
UVM Report ../../t/uvm/dpi/uvm_hdl_verilator.c: 54: UVM/DPI/VLOG_GET Unsupported: uvh_hdl_force/uvm_hdl_release on hdl path 't.exposed'
= uvm_hdl_release
===
UVM Report expected on next line:
UVM Report ../../t/uvm/dpi/uvm_hdl_verilator.c: 54: UVM/DPI/VLOG_GET Unsupported: uvh_hdl_force/uvm_hdl_release on hdl path 't.exposed'
= uvm_hdl_release_and_read
===
UVM Report expected on next line:
UVM Report ../../t/uvm/dpi/uvm_hdl_verilator.c: 54: UVM/DPI/VLOG_GET Unsupported: uvh_hdl_force/uvm_hdl_release on hdl path 't.exposed'
*-* All Finished *-*

20
test_regress/t/t_uvm_dpi.py Executable file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.pli_filename = "t/uvm/dpi/uvm_dpi.cc"
test.compile(
verilator_flags2=["--binary", "--build-jobs 4", "--vpi", "+incdir+t/uvm", test.pli_filename])
test.execute(expect_filename=test.golden_filename)
test.passes()

161
test_regress/t/t_uvm_dpi.v Normal file
View File

@ -0,0 +1,161 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
// verilator lint_off WIDTH
`include "dpi/uvm_dpi.svh"
// verilator lint_on WIDTH
// verilog_format: off
`define stop $stop
`define checkh(gotv, expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
`define checks(gotv, expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
// verilog_format: on
// Undocumented DPI available version of uvm_report
// UVM declares without 'context'
package uvm_pkg;
export "DPI-C" function m__uvm_report_dpi;
function void m__uvm_report_dpi(int severity, string id, string message, int verbosity,
string filename, int line);
$display("UVM Report %s:%d: %s %s", filename, line, id, message);
endfunction : m__uvm_report_dpi
endpackage
module t;
int i;
string s;
chandle h;
// To cover testing cases, this has non-zero LSB/LO
logic [31+8:8] exposed /*verilator public*/;
uvm_hdl_data_t lval;
initial begin
// TODO TEST:
// extern const char* uvm_dpi_get_next_arg_c(int init);
//===== Tool
s = uvm_dpi_get_tool_name_c();
$display("uvm_dpi_get_tool_name_c() = %s", s);
`checks(s, "Verilator");
s = uvm_dpi_get_tool_version_c();
$display("uvm_dpi_get_tool_version_c() = %s", s);
if (s == "") $stop;
//===== Regexp
$display("= uvm_re");
h = uvm_dpi_regcomp("a.*b");
i = uvm_dpi_regexec(h, "__a_b__");
`checkh(i, 0);
i = uvm_dpi_regexec(h, "__a_z__");
`checkh(i, 1);
uvm_dpi_regfree(h);
i = uvm_re_match("a.*b", "__a__b__");
`checkh(i, 0);
i = uvm_re_match("a.*b", "__a__z__");
`checkh(i, 1);
s = uvm_glob_to_re("a foo bar");
`checks(s, "/^a foo bar$/");
//===== Hier
`ifdef VERILATOR
`ifdef TEST_VERBOSE
$c("Verilated::scopesDump();");
`endif
`endif
$display("= uvm_hdl_check_path");
i = uvm_hdl_check_path("t.__NOT_FOUND");
`checkh(i, 0);
i = uvm_hdl_check_path("t.exposed");
`checkh(i, 1);
i = uvm_hdl_check_path("$root.t.exposed");
`checkh(i, 1);
$display("= uvm_hdl_read simple variable");
exposed = 32'hb001;
lval = '0; // Upper bits not cleared by uvm_hdl_read
i = uvm_hdl_read("t.exposed", lval);
`checkh(i, 1);
`checkh(lval[31:0], exposed);
lval = '0;
$display("= uvm_hdl_read not found (bad)");
$display("===\nUVM Report expected on next line:");
i = uvm_hdl_deposit("t.__DEPOSIT_NOT_FOUND", lval);
`checkh(i, 0);
$display("= uvm_hdl_deposit simple variable");
lval = 1024'hab;
i = uvm_hdl_deposit("t.exposed", lval);
`checkh(i, 1);
`checkh(exposed, 32'hab);
$display("= uvm_hdl_read single bit");
exposed = 32'habcd;
lval = '0; // Upper bits not cleared by uvm_hdl_read
i = uvm_hdl_read("t.exposed[11]", lval);
`checkh(i, 1);
`checkh(lval[0], exposed[11]);
$display("= uvm_hdl_deposit single bit");
lval = 1024'h0;
i = uvm_hdl_deposit("t.exposed[11]", lval);
`checkh(i, 1);
`checkh(exposed, 32'habc5);
$display("= uvm_hdl_read multi-bit");
exposed = 32'habcd;
lval = '0; // Upper bits not cleared by uvm_hdl_read
i = uvm_hdl_read("t.exposed[19:12]", lval);
`checkh(i, 1);
`checkh(lval[7:0], exposed[19:12]);
$display("= uvm_hdl_deposit multi-bit");
lval = 1024'h12;
i = uvm_hdl_deposit("t.exposed[19:12]", lval);
`checkh(i, 1);
`checkh(exposed, 32'ha12d);
$display("= uvm_hdl_deposit bad ranges");
$display("===\nUVM Report expected on next line:");
i = uvm_hdl_deposit("t.exposed[10:3]", lval);
`checkh(i, 0);
$display("===\nUVM Report expected on next line:");
i = uvm_hdl_deposit("t.exposed[99:15]", lval);
`checkh(i, 0);
`ifdef VERILATOR
// UNSUPPORTED: force/release via VPI
// If support, validate or throw unsupported on force/release part-selects
$display("= uvm_hdl_force");
$display("===\nUVM Report expected on next line:");
i = uvm_hdl_force("t.exposed", 62);
`checkh(i, 0);
$display("= uvm_hdl_release");
$display("===\nUVM Report expected on next line:");
i = uvm_hdl_release("t.exposed");
`checkh(i, 0);
$display("= uvm_hdl_release_and_read");
$display("===\nUVM Report expected on next line:");
i = uvm_hdl_release_and_read("t.exposed", lval);
`checkh(i, 0);
`endif
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,125 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: DontAlign
AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: All
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 99
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- Q_FOREACH
- BOOST_FOREACH
# Include grouping/sorting
SortIncludes: true
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '"V3Pch.*\.h"'
Priority: -2 # Precompiled headers
- Regex: '"(config_build|verilated_config|verilatedos)\.h"'
Priority: -1 # Sepecials before main header
- Regex: '(<|")verilated.*'
Priority: 1 # Runtime headers
- Regex: '"V3.*__gen.*\.h"'
Priority: 3 # Generated internal headers separately
- Regex: '"V3.*"'
Priority: 2 # Internal header
- Regex: '".*"'
Priority: 4 # Other non-system headers
- Regex: '<[[:alnum:]_.]+>'
Priority: 5 # Simple system headers next
- Regex: '<.*>'
Priority: 6 # Other system headers next
IncludeIsMainRegex: '$'
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 0
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...

View File

@ -0,0 +1,52 @@
//----------------------------------------------------------------------
// Copyright 2010-2011 Mentor Graphics Corporation
// Copyright 2010-2013 Synopsys, Inc.
// Copyright 2010-2018 Cadence Design Systems, Inc.
// Copyright 2010 AMD
// Copyright 2013 NVIDIA Corporation
// 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.
//----------------------------------------------------------------------
// Implementation of common methods for DPI
extern void m__uvm_report_dpi(int,const char*,const char*,int,const char*, int);
#if defined(XCELIUM) || defined(NCSC)
const static char* uvm_package_scope_name = "uvm_pkg::";
#else
const static char* uvm_package_scope_name = "uvm_pkg";
#endif
void m_uvm_report_dpi( int severity,
char* id,
char* message,
int verbosity,
char* file,
int linenum) {
svScope old_scope = svSetScope(svGetScopeFromName(uvm_package_scope_name));
m__uvm_report_dpi(severity, id, message, verbosity, file, linenum);
svSetScope(old_scope);
}
int int_str_max ( int radix_bits ) {
int val = INT_MAX;
int ret = 1;
while ((val = (val /radix_bits)))
ret++;
return ret;
}

View File

@ -0,0 +1,63 @@
//----------------------------------------------------------------------
// Copyright 2010-2017 Mentor Graphics Corporation
// Copyright 2010-2013 Synopsys, Inc.
// Copyright 2010-2018 Cadence Design Systems, Inc.
// Copyright 2013 NVIDIA Corporation
// 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.
//----------------------------------------------------------------------
//
// Top-level file that includes all of the C/C++ files required
// by UVM
//
// The C code may be compiled by compiling this top file only,
// or by compiling individual files then linking them together.
//
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include "uvm_dpi.h"
// Avoid -Wmissing-definitions
int uvm_re_match(const char * re, const char *str);
const char * uvm_glob_to_re(const char *glob);
int uvm_hdl_check_path(char *path);
int uvm_hdl_read(char *path, p_vpi_vecval value);
int uvm_hdl_deposit(char *path, p_vpi_vecval value);
int uvm_hdl_force(char *path, p_vpi_vecval value);
int uvm_hdl_release_and_read(char *path, p_vpi_vecval value);
int uvm_hdl_release(char *path);
void push_data(int lvl,char *entry, int cmd);
void walk_level(int lvl, int argc, char**argv,int cmd);
const char *uvm_dpi_get_next_arg_c (int init);
extern char* uvm_dpi_get_tool_name_c ();
extern char* uvm_dpi_get_tool_version_c ();
extern regex_t* uvm_dpi_regcomp (char* pattern);
extern int uvm_dpi_regexec (regex_t* re, char* str);
extern void uvm_dpi_regfree (regex_t* re);
#include "uvm_common.c"
#include "uvm_regex.cc"
#include "uvm_hdl.c"
#include "uvm_svcmd_dpi.c"
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,84 @@
//----------------------------------------------------------------------
// Copyright 2010-2017 Mentor Graphics Corporation
// Copyright 2010 Synopsys, Inc.
// Copyright 2010-2018 Cadence Design Systems, Inc.
// Copyright 2013 NVIDIA Corporation
// 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.
//----------------------------------------------------------------------
//
// Top level header filke that wraps all requirements which
// are common to the various C/C++ files in UVM.
//
#ifndef UVM_DPI__H
#define UVM_DPI__H
#include <stdlib.h>
#include "vpi_user.h"
#include "veriuser.h"
#include "svdpi.h"
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include <regex.h>
#include <limits.h>
// The following consts and method call are for
// internal usage by the UVM DPI implementation,
// and are not intended for public use.
static const int M_UVM_INFO = 0;
static const int M_UVM_WARNING = 1;
static const int M_UVM_ERROR = 2;
static const int M_UVM_FATAL = 3;
static const int M_UVM_NONE = 0;
static const int M_UVM_LOW = 100;
static const int M_UVM_MEDIUM = 200;
static const int M_UVM_HIGH = 300;
static const int M_UVM_FULL = 400;
static const int M_UVM_DEBUG = 500;
void m_uvm_report_dpi(int severity,
char* id,
char* message,
int verbosity,
char* file,
int linenum);
int int_str_max( int );
int uvm_re_match(const char * re, const char *str);
const char * uvm_glob_to_re(const char *glob);
int uvm_hdl_check_path(char *path);
int uvm_hdl_read(char *path, p_vpi_vecval value);
int uvm_hdl_deposit(char *path, p_vpi_vecval value);
int uvm_hdl_force(char *path, p_vpi_vecval value);
int uvm_hdl_release_and_read(char *path, p_vpi_vecval value);
int uvm_hdl_release(char *path);
void push_data(int lvl,char *entry, int cmd);
void walk_level(int lvl, int argc, char**argv,int cmd);
const char *uvm_dpi_get_next_arg_c (int init);
extern char* uvm_dpi_get_tool_name_c ();
extern char* uvm_dpi_get_tool_version_c ();
extern regex_t* uvm_dpi_regcomp (char* pattern);
extern int uvm_dpi_regexec (regex_t* re, char* str);
extern void uvm_dpi_regfree (regex_t* re);
#endif

View File

@ -0,0 +1,44 @@
//----------------------------------------------------------------------
// Copyright 2010-2011 Mentor Graphics Corporation
// Copyright 2010 Synopsys, Inc.
// Copyright 2010-2018 Cadence Design Systems, Inc.
// Copyright 2010 AMD
// 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.
//----------------------------------------------------------------------
`ifndef UVM_DPI_SVH
`define UVM_DPI_SVH
//
// Top-level file for DPI subroutines used by UVM.
//
// Tool-specific distribution overlays may be required.
//
// To use UVM without any tool-specific overlay, use +defin+UVM_NO_DPI
//
`ifdef UVM_NO_DPI
`define UVM_HDL_NO_DPI
`define UVM_REGEX_NO_DPI
`define UVM_CMDLINE_NO_DPI
`endif
`include "dpi/uvm_hdl.svh"
`include "dpi/uvm_svcmd_dpi.svh"
`include "dpi/uvm_regex.svh"
`endif // UVM_DPI_SVH

View File

@ -0,0 +1,40 @@
//----------------------------------------------------------------------
// Copyright 2009-2011 Mentor Graphics Corporation
// Copyright 2010-2011 Synopsys, Inc.
// Copyright 2007-2018 Cadence Design Systems, Inc.
// Copyright 2013 NVIDIA Corporation
// 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.
//----------------------------------------------------------------------
// hdl vendor backends are defined for VCS,QUESTA,VERILATOR,XCELIUM
#if defined(VCS) || defined(VCSMX)
#include "uvm_hdl_vcs.c"
#else
#ifdef QUESTA
#include "uvm_hdl_questa.c"
#else
#ifdef VERILATOR
#include "uvm_hdl_verilator.c"
#else
#if defined(XCELIUM) || defined(NCSC)
#include "uvm_hdl_xcelium.c"
#else
#error "hdl vendor backend is missing"
#endif
#endif
#endif
#endif

View File

@ -0,0 +1,170 @@
//------------------------------------------------------------
// Copyright 2007-2011 Mentor Graphics Corporation
// Copyright 2015 Analog Devices, Inc.
// Copyright 2010 Synopsys, Inc.
// Copyright 2010-2018 Cadence Design Systems, Inc.
// Copyright 2014-2018 NVIDIA Corporation
// Copyright 2014 Cisco Systems, Inc.
// Copyright 2012 Accellera Systems Initiative
// 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.
//------------------------------------------------------------
// TITLE -- NODOCS -- UVM HDL Backdoor Access support routines.
//
// These routines provide an interface to the DPI/PLI
// implementation of backdoor access used by registers.
//
// If you DON'T want to use the DPI HDL API, then compile your
// SystemVerilog code with the vlog switch
//: vlog ... +define+UVM_HDL_NO_DPI ...
//
`ifndef UVM_HDL__SVH
`define UVM_HDL__SVH
`ifndef UVM_HDL_MAX_WIDTH
`define UVM_HDL_MAX_WIDTH 1024
`endif
/*
* VARIABLE -- NODOCS -- UVM_HDL_MAX_WIDTH
* Sets the maximum size bit vector for backdoor access.
* This parameter will be looked up by the
* DPI-C code using:
* vpi_handle_by_name(
* "uvm_pkg::UVM_HDL_MAX_WIDTH", 0);
*/
// @uvm-ieee 1800.2-2020 manual 19.6.1
parameter int UVM_HDL_MAX_WIDTH = `UVM_HDL_MAX_WIDTH;
typedef logic [UVM_HDL_MAX_WIDTH-1:0] uvm_hdl_data_t;
`ifndef UVM_HDL_NO_DPI
// Function -- NODOCS -- uvm_hdl_check_path
//
// Checks that the given HDL ~path~ exists. Returns 0 if NOT found, 1 otherwise.
//
import "DPI-C" context function int uvm_hdl_check_path(string path);
// Function -- NODOCS -- uvm_hdl_deposit
//
// Sets the given HDL ~path~ to the specified ~value~.
// Returns 1 if the call succeeded, 0 otherwise.
//
import "DPI-C" context function int uvm_hdl_deposit(string path, uvm_hdl_data_t value);
// Function -- NODOCS -- uvm_hdl_force
//
// Forces the ~value~ on the given ~path~. Returns 1 if the call succeeded, 0 otherwise.
//
import "DPI-C" context function int uvm_hdl_force(string path, uvm_hdl_data_t value);
// Function -- NODOCS -- uvm_hdl_force_time
//
// Forces the ~value~ on the given ~path~ for the specified amount of ~force_time~.
// If ~force_time~ is 0, <uvm_hdl_deposit> is called.
// Returns 1 if the call succeeded, 0 otherwise.
//
task uvm_hdl_force_time(string path, uvm_hdl_data_t value, time force_time = 0);
if (force_time == 0) begin
void'(uvm_hdl_deposit(path, value));
return;
end
if (!uvm_hdl_force(path, value))
return;
#force_time;
void'(uvm_hdl_release_and_read(path, value));
endtask
// Function -- NODOCS -- uvm_hdl_release_and_read
//
// Releases a value previously set with <uvm_hdl_force>.
// Returns 1 if the call succeeded, 0 otherwise. ~value~ is set to
// the HDL value after the release. For 'reg', the value will still be
// the forced value until it has been procedurally reassigned. For 'wire',
// the value will change immediately to the resolved value of its
// continuous drivers, if any. If none, its value remains as forced until
// the next direct assignment.
//
import "DPI-C" context function int uvm_hdl_release_and_read(string path, inout uvm_hdl_data_t value);
// Function -- NODOCS -- uvm_hdl_release
//
// Releases a value previously set with <uvm_hdl_force>.
// Returns 1 if the call succeeded, 0 otherwise.
//
import "DPI-C" context function int uvm_hdl_release(string path);
// Function -- NODOCS -- uvm_hdl_read()
//
// Gets the value at the given ~path~.
// Returns 1 if the call succeeded, 0 otherwise.
//
import "DPI-C" context function int uvm_hdl_read(string path, output uvm_hdl_data_t value);
`else
function int uvm_hdl_check_path(string path);
uvm_report_fatal("UVM_HDL_CHECK_PATH",
$sformatf("uvm_hdl DPI routines are compiled off. Recompile without +define+UVM_HDL_NO_DPI"));
return 0;
endfunction
function int uvm_hdl_deposit(string path, uvm_hdl_data_t value);
uvm_report_fatal("UVM_HDL_DEPOSIT",
$sformatf("uvm_hdl DPI routines are compiled off. Recompile without +define+UVM_HDL_NO_DPI"));
return 0;
endfunction
function int uvm_hdl_force(string path, uvm_hdl_data_t value);
uvm_report_fatal("UVM_HDL_FORCE",
$sformatf("uvm_hdl DPI routines are compiled off. Recompile without +define+UVM_HDL_NO_DPI"));
return 0;
endfunction
task uvm_hdl_force_time(string path, uvm_hdl_data_t value, time force_time=0);
uvm_report_fatal("UVM_HDL_FORCE_TIME",
$sformatf("uvm_hdl DPI routines are compiled off. Recompile without +define+UVM_HDL_NO_DPI"));
endtask
function int uvm_hdl_release(string path);
uvm_report_fatal("UVM_HDL_RELEASE",
$sformatf("uvm_hdl DPI routines are compiled off. Recompile without +define+UVM_HDL_NO_DPI"));
return 0;
endfunction
function int uvm_hdl_read(string path, output uvm_hdl_data_t value);
uvm_report_fatal("UVM_HDL_READ",
$sformatf("uvm_hdl DPI routines are compiled off. Recompile without +define+UVM_HDL_NO_DPI"));
return 0;
endfunction
`endif
`endif

View File

@ -0,0 +1,342 @@
//----------------------------------------------------------------------
// Copyright 2007-2023 Cadence Design Systems, Inc.
// Copyright 2009-2011 Mentor Graphics Corporation
// Copyright 2013-2024 NVIDIA Corporation
// Copyright 2010-2011 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.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Git details (see DEVELOPMENT.md):
//
// $File$
// $Rev$
// $Hash$
//
//----------------------------------------------------------------------
#include "svdpi.h"
#include "vpi_user.h"
#include <malloc.h>
#include <stdio.h>
#include <string.h>
static void m_uvm_error(const char *ID, const char *msg, ...);
static int uvm_hdl_set_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag);
static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag, int partsel);
static int uvm_hdl_max_width();
// static print buffer
static char m_uvm_temp_print_buffer[1024];
// static print error
static void m_uvm_error(const char *id, const char *msg, ...) {
va_list argptr;
va_start(argptr, msg);
vsprintf(m_uvm_temp_print_buffer, msg, argptr);
va_end(argptr);
m_uvm_report_dpi(M_UVM_ERROR, (char *)id, &m_uvm_temp_print_buffer[0], M_UVM_NONE,
(char *)__FILE__, __LINE__);
}
/*
* UVM HDL access C code.
*
*/
/*
* This C code checks to see if there is PLI handle
* with a value set to define the maximum bit width.
*
* If no such variable is found, then the default
* width of 1024 is used.
*
* This function should only get called once or twice,
* its return value is cached in the caller.
*
*/
static int UVM_HDL_MAX_WIDTH = 0;
static int uvm_hdl_max_width() {
if (!UVM_HDL_MAX_WIDTH) {
vpiHandle ms;
s_vpi_value value_s = {vpiIntVal, {0}};
ms = vpi_handle_by_name((PLI_BYTE8 *)"uvm_pkg::UVM_HDL_MAX_WIDTH", 0);
if (ms == 0) {
UVM_HDL_MAX_WIDTH = 1024; /* If nothing else is defined, this is the DEFAULT */
} else {
vpi_get_value(ms, &value_s);
UVM_HDL_MAX_WIDTH = value_s.value.integer;
}
}
return UVM_HDL_MAX_WIDTH;
}
/*
* Internals: Given a path, look at the path name and determine
* the handle and any partsel's needed to access it.
*/
static vpiHandle uvm_hdl_handle_by_name_partsel(char *path, int *is_partsel_ptr, int *hi_ptr,
int *lo_ptr) {
vpiHandle r;
char *path_ptr;
char *path_base_ptr;
int temp;
*is_partsel_ptr = 0;
if (!path || !path[0]) return 0;
// If direct lookup works, go with that
r = vpi_handle_by_name(path, 0);
if (r) return r;
// Find array subscript
path_ptr = (char *)(path + strlen(path) - 1);
if (*path_ptr != ']') return 0;
while (path_ptr != path && *path_ptr != ':' && *path_ptr != '[') --path_ptr;
if (path_ptr == path) return 0;
*lo_ptr = *hi_ptr = atoi(path_ptr + 1);
*is_partsel_ptr = 1;
if (*path_ptr == ':') {
--path_ptr; // back over :
while (path_ptr != path && *path_ptr != '[') --path_ptr;
*hi_ptr = atoi(path_ptr + 1);
if (path_ptr == path) return 0;
}
if (*lo_ptr > *hi_ptr) {
temp = *lo_ptr;
*lo_ptr = *hi_ptr;
*hi_ptr = temp;
}
path_base_ptr = strndup(path, (path_ptr - path));
r = vpi_handle_by_name(path_base_ptr, 0);
if (!r) return 0;
{
vpiHandle rh;
s_vpi_value value;
int decl_ranged = 0;
int decl_lo;
int decl_hi;
int decl_left = -1;
int decl_right = -1;
rh = vpi_handle(vpiLeftRange, r);
if (rh) {
value.format = vpiIntVal;
vpi_get_value(rh, &value);
decl_left = value.value.integer;
vpi_release_handle(rh);
}
rh = vpi_handle(vpiRightRange, r);
if (rh) {
value.format = vpiIntVal;
vpi_get_value(rh, &value);
decl_ranged = 1;
decl_right = value.value.integer;
vpi_release_handle(rh);
}
if (!decl_ranged) {
// vpi_printf((PLI_BYTE8 *)"Outside declaration '%s' range %d:%d\n",
// path, decl_left, decl_right);
return 0;
}
// vpi_printf((PLI_BYTE8 *)"%s:%d: req %d:%d decl %d:%d for '%s'\n",
// __FILE__, __LINE__, *hi_ptr, *lo_ptr, decl_left, decl_right, path);
decl_lo = (decl_left < decl_right) ? decl_left : decl_right;
decl_hi = (decl_left > decl_right) ? decl_left : decl_right;
if (*lo_ptr < decl_lo) return 0;
if (*hi_ptr > decl_hi) return 0;
*lo_ptr -= decl_lo;
*hi_ptr -= decl_lo;
}
return r;
}
/*
* Given a path, look the path name up using the PLI,
* and set it to 'value'.
*/
static int uvm_hdl_set_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag) {
vpiHandle r;
s_vpi_value value_s = {vpiIntVal, {0}};
s_vpi_time time_s = {vpiSimTime, 0, 0, 0.0};
int is_partsel, hi, lo;
int size;
static int s_maxsize = -1;
if (flag == vpiForceFlag || flag == vpiReleaseFlag) {
// It appears other simulator interfaces likewise don't support this
m_uvm_error("UVM/DPI/VLOG_GET", "Unsupported: uvh_hdl_force/uvm_hdl_release on hdl path '%s'",
path);
return 0;
}
r = uvm_hdl_handle_by_name_partsel(path, &is_partsel, &hi, &lo);
if (r == 0) {
m_uvm_error("UVM/DPI/HDL_SET",
"set: unable to locate hdl path (%s)\n Either the name is incorrect, "
"or you may not have PLI/ACC visibility to that name",
path);
return 0;
}
if (!is_partsel) {
value_s.format = vpiVectorVal;
value_s.value.vector = value;
vpi_put_value(r, &value_s, &time_s, flag);
} else {
if (s_maxsize == -1) s_maxsize = uvm_hdl_max_width();
size = vpi_get(vpiSize, r);
if (size > s_maxsize) {
m_uvm_error("UVM/DPI/VLOG_PUT",
"hdl path '%s' is %0d bits, but the maximum size is %0d. "
"You can increase the maximum via a compile-time flag: "
"+define+UVM_HDL_MAX_WIDTH=<value>",
path, size, s_maxsize);
vpi_release_handle(r);
return 0;
}
value_s.format = vpiVectorVal;
vpi_get_value(r, &value_s);
for (int i = 0; i < (((hi - lo + 1) / 32) + 1); ++i) {
int subsize = hi - (lo + (i << 5)) + 1;
if (subsize > 32) subsize = 32;
svPutPartselLogic(&value_s.value.vector[i], value[i], lo + (i << 5), subsize);
}
vpi_put_value(r, &value_s, &time_s, flag);
}
vpi_release_handle(r);
return 1;
}
/*
* Given a path, look the path name up using the PLI
* and return its 'value'.
*/
static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag, int partsel) {
static int s_maxsize = -1;
int i, size, chunks;
vpiHandle r;
s_vpi_value value_s;
int is_partsel, hi, lo;
r = uvm_hdl_handle_by_name_partsel(path, &is_partsel, &hi, &lo);
if (r == 0) {
m_uvm_error("UVM/DPI/VLOG_GET",
"unable to locate hdl path (%s)\n Either the name is incorrect, or you "
"may not have PLI/ACC visibility to that name",
path);
return 0;
}
if (s_maxsize == -1) s_maxsize = uvm_hdl_max_width();
size = vpi_get(vpiSize, r);
if (size > s_maxsize) {
m_uvm_error("UVM/DPI/VLOG_GET",
"hdl path '%s' is %0d bits, but the maximum size is %0d. "
"You can increase the maximum via a compile-time flag: "
"+define+UVM_HDL_MAX_WIDTH=<value>",
path, size, s_maxsize);
vpi_release_handle(r);
return 0;
}
chunks = (size - 1) / 32 + 1;
value_s.format = vpiVectorVal;
vpi_get_value(r, &value_s);
// Note upper bits are not cleared, other simulators do likewise
if (!is_partsel) {
// Keep as separate branch as subroutine can potentially inline and highly optimize
for (i = 0; i < chunks; ++i) {
value[i].aval = value_s.value.vector[i].aval;
value[i].bval = value_s.value.vector[i].bval;
}
} else {
// Verilator supports > 32 bit widths, which is an extension to IEEE DPI
svGetPartselLogic(value, value_s.value.vector, lo, hi - lo + 1);
}
// vpi_printf((PLI_BYTE8 *)"uvm_hdl_get_vlog(%s,%0x)\n", path, value[0].aval);
vpi_release_handle(r);
return 1;
}
/*
* Given a path, look the path name up using the PLI,
* but don't set or get. Just check.
*
* Return 0 if NOT found.
* Return 1 if found.
*/
int uvm_hdl_check_path(char *path) {
vpiHandle handle;
handle = vpi_handle_by_name(path, 0);
return (handle != 0);
}
/*
* Given a path, look the path name up using the PLI
* or the FLI, and return its 'value'.
*/
int uvm_hdl_read(char *path, p_vpi_vecval value) {
return uvm_hdl_get_vlog(path, value, vpiNoDelay, 0);
}
/*
* Given a path, look the path name up using the PLI
* or the FLI, and set it to 'value'.
*/
int uvm_hdl_deposit(char *path, p_vpi_vecval value) {
return uvm_hdl_set_vlog(path, value, vpiNoDelay);
}
/*
* Given a path, look the path name up using the PLI
* or the FLI, and set it to 'value'.
*/
int uvm_hdl_force(char *path, p_vpi_vecval value) {
return uvm_hdl_set_vlog(path, value, vpiForceFlag);
}
/*
* Given a path, look the path name up using the PLI
* or the FLI, and release it.
*/
int uvm_hdl_release_and_read(char *path, p_vpi_vecval value) {
return uvm_hdl_set_vlog(path, value, vpiReleaseFlag);
}
/*
* Given a path, look the path name up using the PLI
* or the FLI, and release it.
*/
int uvm_hdl_release(char *path) {
s_vpi_vecval value;
return uvm_hdl_set_vlog(path, &value, vpiReleaseFlag);
}

View File

@ -0,0 +1,239 @@
//----------------------------------------------------------------------
// Copyright 2007-2011 Mentor Graphics Corporation
// Copyright 2010-2018 Cadence Design Systems, Inc.
// Copyright 2013-2014 NVIDIA Corporation
// 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.
//----------------------------------------------------------------------
#include "uvm_dpi.h"
#include <sys/types.h>
const char uvm_re_bracket_char = '/';
#define UVM_REGEX_MAX_LENGTH 2048
static char uvm_re[UVM_REGEX_MAX_LENGTH+4];
static const char* empty_regex="/^$/";
//--------------------------------------------------------------------
// uvm_re_match
//
// Match a string to a regular expression. The regex is first lookup
// up in the regex cache to see if it has already been compiled. If
// so, the compile version is retrieved from the cache. Otherwise, it
// is compiled and cached for future use. After compilation the
// matching is done using regexec().
//--------------------------------------------------------------------
int uvm_re_match(const char * re, const char *str)
{
regex_t *rexp;
int err;
// safety check. Args should never be ~null~ since this is called
// from DPI. But we'll check anyway.
if(re == NULL)
return 1;
if(str == NULL)
return 1;
int len = strlen(re);
char * rex = &uvm_re[0];
if (len > UVM_REGEX_MAX_LENGTH) {
const char* err_str = "uvm_re_match : regular expression greater than max %0d: |%s|";
char buffer[strlen(err_str) + int_str_max(10) + strlen(re)];
sprintf(buffer, err_str, UVM_REGEX_MAX_LENGTH, re);
m_uvm_report_dpi(M_UVM_ERROR,
(char*) "UVM/DPI/REGEX_MAX",
&buffer[0],
M_UVM_NONE,
(char*)__FILE__,
__LINE__);
return 1;
}
// we copy the regexp because we need to remove any brackets around it
strncpy(&uvm_re[0],re,UVM_REGEX_MAX_LENGTH);
if (len>1 && (re[0] == uvm_re_bracket_char) && re[len-1] == uvm_re_bracket_char) {
uvm_re[len-1] = '\0';
rex++;
}
rexp = (regex_t*)malloc(sizeof(regex_t));
if (rexp == NULL) {
m_uvm_report_dpi(M_UVM_ERROR,
(char*) "UVM/DPI/REGEX_ALLOC",
(char*) "uvm_re_match: internal memory allocation error",
M_UVM_NONE,
(char*)__FILE__,
__LINE__);
return 1;
}
err = regcomp(rexp, rex, REG_EXTENDED);
if (err != 0) {
regerror(err,rexp,uvm_re,UVM_REGEX_MAX_LENGTH-1);
const char * err_str = "uvm_re_match : invalid glob or regular expression: |%s||%s|";
char buffer[strlen(err_str) + strlen(re) + strlen(uvm_re)+1];
sprintf(buffer, err_str, re, uvm_re);
m_uvm_report_dpi(M_UVM_ERROR,
(char*) "UVM/DPI/REGEX_INV",
&buffer[0],
M_UVM_NONE,
(char*)__FILE__,
__LINE__);
regfree(rexp);
free(rexp);
return err;
}
err = regexec(rexp, str, 0, NULL, 0);
//vpi_printf((PLI_BYTE8*) "UVM_INFO: uvm_re_match: re=%s str=%s ERR=%0d\n",rex,str,err);
regfree(rexp);
free(rexp);
return err;
}
//--------------------------------------------------------------------
// uvm_glob_to_re
//
// Convert a glob expression to a normal regular expression.
//--------------------------------------------------------------------
const char * uvm_glob_to_re(const char *glob)
{
const char *p;
int len;
// safety check. Glob should never be ~null~ since this is called
// from DPI. But we'll check anyway.
if(glob == NULL)
return NULL;
len = strlen(glob);
if (len > 2040) {
const char * err_str = "uvm_re_match : glob expression greater than max 2040: |%s|";
char buffer[strlen(err_str) + strlen(glob)+1];
sprintf(buffer, err_str, glob);
m_uvm_report_dpi(M_UVM_ERROR,
(char*) "UVM/DPI/REGEX_MAX",
&buffer[0],
M_UVM_NONE,
(char*)__FILE__,
__LINE__);
return glob;
}
// If either of the following cases appear then return an empty string
//
// 1. The glob string is empty (it has zero characters)
// 2. The glob string has a single character that is the
// uvm_re_bracket_char (i.e. "/")
if(len == 0 || (len == 1 && *glob == uvm_re_bracket_char))
{
return empty_regex;
}
// If bracketed with the /glob/, then it's already a regex
if(glob[0] == uvm_re_bracket_char && glob[len-1] == uvm_re_bracket_char)
{
strcpy(uvm_re,glob);
return &uvm_re[0];
}
else
{
// Convert the glob to a true regular expression (Posix syntax)
len = 0;
uvm_re[len++] = uvm_re_bracket_char;
// ^ goes at the beginning...
if (*glob != '^')
uvm_re[len++] = '^';
for(p = glob; *p; p++)
{
// Replace the glob metacharacters with corresponding regular
// expression metacharacters.
switch(*p)
{
case '*':
uvm_re[len++] = '.';
uvm_re[len++] = '*';
break;
case '+':
uvm_re[len++] = '.';
uvm_re[len++] = '+';
break;
case '.':
uvm_re[len++] = '\\';
uvm_re[len++] = '.';
break;
case '?':
uvm_re[len++] = '.';
break;
case '[':
uvm_re[len++] = '\\';
uvm_re[len++] = '[';
break;
case ']':
uvm_re[len++] = '\\';
uvm_re[len++] = ']';
break;
case '(':
uvm_re[len++] = '\\';
uvm_re[len++] = '(';
break;
case ')':
uvm_re[len++] = '\\';
uvm_re[len++] = ')';
break;
default:
uvm_re[len++] = *p;
break;
}
}
}
// Let's check to see if the regular expression is bounded by ^ at
// the beginning and $ at the end. If not, add those characters in
// the appropriate position.
if (uvm_re[len-1] != '$')
uvm_re[len++] = '$';
uvm_re[len++] = uvm_re_bracket_char;
uvm_re[len++] = '\0';
return &uvm_re[0];
}

View File

@ -0,0 +1,85 @@
//----------------------------------------------------------------------
// Copyright 2010-2012 Mentor Graphics Corporation
// Copyright 2010-2018 Cadence Design Systems, 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.
//----------------------------------------------------------------------
`ifndef UVM_REGEX_NO_DPI
import "DPI-C" context function int uvm_re_match(string re, string str);
import "DPI-C" context function string uvm_glob_to_re(string glob);
`else
// The Verilog only version does not match regular expressions,
// it only does glob style matching.
function int uvm_re_match(string re, string str);
int e, es, s, ss;
string tmp;
e = 0; s = 0;
es = 0; ss = 0;
if(re.len() == 0)
return 0;
// The ^ used to be used to remove the implicit wildcard, but now we don't
// use implicit wildcard so this character is just stripped.
if(re[0] == "^")
re = re.substr(1, re.len()-1);
//This loop is only needed when the first character of the re may not
//be a *.
while (s != str.len() && re.getc(e) != "*") begin
if ((re.getc(e) != str.getc(s)) && (re.getc(e) != "?"))
return 1;
e++; s++;
end
while (s != str.len()) begin
if (re.getc(e) == "*") begin
e++;
if (e == re.len()) begin
return 0;
end
es = e;
ss = s+1;
end
else if (re.getc(e) == str.getc(s) || re.getc(e) == "?") begin
e++;
s++;
end
else begin
e = es;
s = ss++;
end
end
while (e < re.len() && re.getc(e) == "*")
e++;
if(e == re.len()) begin
return 0;
end
else begin
return 1;
end
endfunction
function string uvm_glob_to_re(string glob);
return glob;
endfunction
`endif

View File

@ -0,0 +1,135 @@
//
//------------------------------------------------------------------------------
// Copyright 2011-2014 Mentor Graphics Corporation
// Copyright 2011-2018 Cadence Design Systems, Inc.
// Copyright 2010-2012 AMD
// Copyright 2013 NVIDIA Corporation
// 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.
//------------------------------------------------------------------------------
#include "uvm_dpi.h"
#include <assert.h>
#define ARGV_STACK_PTR_SIZE 32
// the total number of arguments (minus the -f/-F minus associated filenames)
int argc_total;
// the ptr to the array of ptrs to the args
char** argv_stack=NULL;
char ** argv_ptr=NULL;
void push_data(int lvl,char *entry, int cmd) {
if(cmd==0)
argc_total++;
else
*argv_ptr++=entry;
}
// walk one level (potentially recursive)
void walk_level(int lvl, int argc, char**argv,int cmd) {
int idx;
for(idx=0; ((lvl==0) && idx<argc) || ((lvl>0) && (*argv));idx++,argv++) {
if(strcmp(*argv, "-f") && strcmp(*argv, "-F")) {
push_data(lvl,*argv,cmd);
} else {
argv++;
idx++;
char **n=(char**) *argv;
walk_level(lvl+1,argc,++n,cmd);
}
}
}
const char *uvm_dpi_get_next_arg_c (int init) {
s_vpi_vlog_info info;
static int idx=0;
if(init==1)
{
// free if necessary
free(argv_stack);
argc_total=0;
vpi_get_vlog_info(&info);
walk_level(0,info.argc,info.argv,0);
argv_stack = (char**) malloc (sizeof(char*)*argc_total);
argv_ptr=argv_stack;
walk_level(0,info.argc,info.argv,1);
idx=0;
argv_ptr=argv_stack;
}
if(idx++>=argc_total)
return NULL;
return *argv_ptr++;
}
extern char* uvm_dpi_get_tool_name_c ()
{
s_vpi_vlog_info info;
vpi_get_vlog_info(&info);
return info.product;
}
extern char* uvm_dpi_get_tool_version_c ()
{
s_vpi_vlog_info info;
vpi_get_vlog_info(&info);
return info.version;
}
extern regex_t* uvm_dpi_regcomp (char* pattern)
{
regex_t* re = (regex_t*) malloc (sizeof(regex_t));
int status = regcomp(re, pattern, REG_NOSUB|REG_EXTENDED);
if(status)
{
const char * err_str = "uvm_dpi_regcomp : Unable to compile regex: |%s|, Element 0 is: %c";
char buffer[strlen(err_str) + strlen(pattern) + 1];
sprintf(buffer, err_str, pattern, pattern[0]);
m_uvm_report_dpi(M_UVM_ERROR,
(char*)"UVM/DPI/REGCOMP",
&buffer[0],
M_UVM_NONE,
(char*) __FILE__,
__LINE__);
regfree(re);
free (re);
return NULL;
}
return re;
}
extern int uvm_dpi_regexec (regex_t* re, char* str)
{
if(!re )
{
return 1;
}
return regexec(re, str, (size_t)0, NULL, 0);
}
extern void uvm_dpi_regfree (regex_t* re)
{
if(!re) return;
regfree(re);
free (re);
}

View File

@ -0,0 +1,65 @@
//
//------------------------------------------------------------------------------
// Copyright 2010-2011 Mentor Graphics Corporation
// Copyright 2013-2018 Cadence Design Systems, Inc.
// Copyright 2010-2012 AMD
// 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.
//------------------------------------------------------------------------------
// Import DPI functions used by the interface to generate the
// lists.
`ifndef UVM_CMDLINE_NO_DPI
import "DPI-C" function string uvm_dpi_get_next_arg_c (int init);
import "DPI-C" function string uvm_dpi_get_tool_name_c ();
import "DPI-C" function string uvm_dpi_get_tool_version_c ();
function string uvm_dpi_get_next_arg(int init=0);
return uvm_dpi_get_next_arg_c(init);
endfunction
function string uvm_dpi_get_tool_name();
return uvm_dpi_get_tool_name_c();
endfunction
function string uvm_dpi_get_tool_version();
return uvm_dpi_get_tool_version_c();
endfunction
import "DPI-C" function chandle uvm_dpi_regcomp(string regex);
import "DPI-C" function int uvm_dpi_regexec(chandle preg, string str);
import "DPI-C" function void uvm_dpi_regfree(chandle preg);
`else
function string uvm_dpi_get_next_arg(int init=0);
return "";
endfunction
function string uvm_dpi_get_tool_name();
return "?";
endfunction
function string uvm_dpi_get_tool_version();
return "?";
endfunction
function chandle uvm_dpi_regcomp(string regex); return null; endfunction
function int uvm_dpi_regexec(chandle preg, string str); return 0; endfunction
function void uvm_dpi_regfree(chandle preg); endfunction
`endif