-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Few improvements to VpiListener and removing dead code
* Introducing visited & callback to VpiListener (like UhdmListener) Also, merged the logic in vpi_listener into VpiListener itself to get access to both these containers easily in enter/leave callbacks. * Removed parent and parentHandle parameters from VpiListener::enter/leave. The parameter itself was misleading since it was called 'parent' but it may not actually be the true parent of the object in the callback. The pointer was really the object right below the one on top of the callback hierarchy. The true parent is available via object->VpiParent() and access to the call hierarchy is available via callstack. Thus making both these parameters unnecessary. * VpiListener also has a callback function (enter|leave)Any which gets called at most once for every visited object. For logic that's identical for a number of types, this is ideal place to implement it rather than having to override n number of functions and cloning the logic. * Fixed up all VpiListener sub-classes like UhdmLint and SynthSubset
- Loading branch information
1 parent
db3298c
commit ee1e456
Showing
26 changed files
with
686 additions
and
1,727 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import config | ||
import file_utils | ||
|
||
|
||
def _get_listeners(classname, vpi, type, card): | ||
listeners = [] | ||
|
||
if card == '1': | ||
# upward vpiModule, vpiInterface relation (when card == 1, pointing to the parent object) creates loops in visitors | ||
if vpi in ['vpiParent', 'vpiInstance', 'vpiModule', 'vpiInterface', 'vpiUse', 'vpiProgram', 'vpiClassDefn', 'vpiPackage', 'vpiUdp']: | ||
return listeners | ||
|
||
if 'func_call' in classname and vpi == 'vpiFunction': | ||
# Prevent stepping inside functions while processing calls (func_call, method_func_call) to them | ||
return listeners | ||
|
||
if 'task_call' in classname and vpi == 'vpiTask': | ||
# Prevent stepping inside tasks while processing calls (task_call, method_task_call) to them | ||
return listeners | ||
|
||
listeners.append(f' if (vpiHandle itr = vpi_handle({vpi}, handle)) {{') | ||
listeners.append(f' listenAny(itr);') | ||
listeners.append( ' vpi_free_object(itr);') | ||
listeners.append( ' }') | ||
|
||
else: | ||
listeners.append(f' if (vpiHandle itr = vpi_iterate({vpi}, handle)) {{') | ||
listeners.append( ' while (vpiHandle obj = vpi_scan(itr)) {') | ||
listeners.append(f' listenAny(obj);') | ||
listeners.append( ' vpi_free_object(obj);') | ||
listeners.append( ' }') | ||
listeners.append( ' vpi_free_object(itr);') | ||
listeners.append( ' }') | ||
|
||
return listeners | ||
|
||
|
||
def generate(models): | ||
private_declarations = [] | ||
private_implementations = [] | ||
public_implementations = [] | ||
classnames = set() | ||
|
||
for model in models.values(): | ||
modeltype = model['type'] | ||
if modeltype == 'group_def': | ||
continue | ||
|
||
classname = model['name'] | ||
Classname_ = classname[:1].upper() + classname[1:] | ||
|
||
baseclass = model.get('extends') | ||
|
||
if model.get('subclasses') or modeltype == 'obj_def': | ||
private_declarations.append(f' void listen{Classname_}_(vpiHandle handle);') | ||
private_implementations.append(f'void VpiListener::listen{Classname_}_(vpiHandle handle) {{') | ||
if baseclass: | ||
Baseclass_ = baseclass[:1].upper() + baseclass[1:] | ||
private_implementations.append(f' listen{Baseclass_}_(handle);') | ||
|
||
for key, value in model.allitems(): | ||
if key in ['class', 'obj_ref', 'class_ref', 'group_ref']: | ||
vpi = value.get('vpi') | ||
type = value.get('type') | ||
card = value.get('card') | ||
|
||
if key == 'group_ref': | ||
type = 'any' | ||
|
||
private_implementations.extend(_get_listeners(classname, vpi, type, card)) | ||
|
||
private_implementations.append( '}') | ||
private_implementations.append( '') | ||
|
||
if modeltype != 'class_def': | ||
classnames.add(classname) | ||
|
||
public_implementations.append(f'void VpiListener::listen{Classname_}(vpiHandle handle) {{') | ||
public_implementations.append(f' const {classname}* object = (const {classname}*) ((const uhdm_handle*)handle)->object;') | ||
public_implementations.append(f' callstack.push_back(object);') | ||
public_implementations.append(f' enter{Classname_}(object, handle);') | ||
public_implementations.append( ' if (visited.insert(object).second) {') | ||
public_implementations.append(f' listen{Classname_}_(handle);') | ||
public_implementations.append( ' }') | ||
public_implementations.append(f' leave{Classname_}(object, handle);') | ||
public_implementations.append(f' callstack.pop_back();') | ||
public_implementations.append(f'}}') | ||
public_implementations.append( '') | ||
|
||
any_implementation = [] | ||
enter_leave_declarations = [] | ||
public_declarations = [] | ||
for classname in sorted(classnames): | ||
Classname_ = classname[:1].upper() + classname[1:] | ||
|
||
any_implementation.append(f' case uhdm{classname}: listen{Classname_}(handle); break;') | ||
|
||
enter_leave_declarations.append(f' virtual void enter{Classname_}(const {classname}* object, vpiHandle handle) {{}}') | ||
enter_leave_declarations.append(f' virtual void leave{Classname_}(const {classname}* object, vpiHandle handle) {{}}') | ||
enter_leave_declarations.append( '') | ||
|
||
public_declarations.append(f' void listen{Classname_}(vpiHandle handle);') | ||
|
||
# VpiListener.h | ||
with open(config.get_template_filepath('VpiListener.h'), 'rt') as strm: | ||
file_content = strm.read() | ||
|
||
file_content = file_content.replace('<VPI_PUBLIC_LISTEN_DECLARATIONS>', '\n'.join(public_declarations)) | ||
file_content = file_content.replace('<VPI_PRIVATE_LISTEN_DECLARATIONS>', '\n'.join(private_declarations)) | ||
file_content = file_content.replace('<VPI_ENTER_LEAVE_DECLARATIONS>', '\n'.join(enter_leave_declarations)) | ||
file_utils.set_content_if_changed(config.get_output_header_filepath('VpiListener.h'), file_content) | ||
|
||
# VpiListener.cpp | ||
with open(config.get_template_filepath('VpiListener.cpp'), 'rt') as strm: | ||
file_content = strm.read() | ||
|
||
file_content = file_content.replace('<VPI_PRIVATE_LISTEN_IMPLEMENTATIONS>', '\n'.join(private_implementations)) | ||
file_content = file_content.replace('<VPI_PUBLIC_LISTEN_IMPLEMENTATIONS>', '\n'.join(public_implementations)) | ||
file_content = file_content.replace('<VPI_LISTENANY_IMPLEMENTATION>', '\n'.join(any_implementation)) | ||
file_utils.set_content_if_changed(config.get_output_source_filepath('VpiListener.cpp'), file_content) | ||
|
||
return True | ||
|
||
|
||
def _main(): | ||
import loader | ||
|
||
config.configure() | ||
|
||
models = loader.load_models() | ||
return generate(models) | ||
|
||
|
||
if __name__ == '__main__': | ||
import sys | ||
sys.exit(0 if _main() else 1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.