chipsalliance / Surelog

SystemVerilog 2017 Pre-processor, Parser, Elaborator, UHDM Compiler. Provides IEEE Design/TB C/C++ VPI and Python AST & UHDM APIs. Compiles on Linux gcc, Windows msys2-gcc & msvc, OsX
Apache License 2.0
366 stars 69 forks source link

Q: What's the best way to compute the width of a uhdmoperation? #3472

Closed mysoreanoop closed 1 year ago

mysoreanoop commented 1 year ago

Aim: To compute width of vpiCondition within a UHDM::uhdmcase_stmt

So far: I'm switching based on vpiCondition being part_sel, bit_sel, ref_obj, expr, operation, hier_path, etc., and computing the widths at the leaves and summing them at various intermediate nodes.

Seeking: Is there an existing function or better/simpler way to do this?

Thomasb81 commented 1 year ago

Are you trying to evaluate an expression ? if yes I would refer to chapter 11.6 Expression bit lengths of SV standard.

mysoreanoop commented 1 year ago

Table 11-21 in there is what I was looking for, thanks!

Is there an existing function that I can leverage or modify for implementing this?

alaindargelas commented 1 year ago

https://github.com/chipsalliance/UHDM/blob/7d0cd8dbaf3738559cddcf78bcdf04515067c311/templates/ExprEval.h#L60

I suppose you are using the VPI API. From any VPI handle, you can get it's UHDM C++ object: include https://github.com/chipsalliance/UHDM/blob/master/templates/vpi_uhdm.h

vpiHandle handle = .....

any uhdmHandle = ((uhdm_handle)handle)->object;

(Someone has to submit a PR in UHDM to create a function that does that conversion)

Then use the UHDM:ExprEval::size( ..... ) method to evaluate the size of the condition which is an expression. If it is not complete, then please submit a PR to complete it. It needs context like instance, but you must have that context in the form of a vpiHandle for the instance you are visiting.

alaindargelas commented 1 year ago

@mysoreanoop do you need more help with this issue?

mysoreanoop commented 1 year ago

Yes please, here's what I have so far: (this is probably a C++ error)

std::string visitCond(vpiHandle h) {
  std::cout << "Walking condition; type: " <<
    UHDM::UhdmName((UHDM::UHDM_OBJECT_TYPE)((const uhdm_handle *)h)->type) << std::endl;
  // at this point, the vpiHandle is, for simplicity, ref_obj or hier_path or operation only;
  const UHDM::any* op_obj = (const UHDM::any *)((uhdm_handle *)h)->object;  if(op_obj)
  if(op_obj)
    std::cout <<  UHDM::ExprEval::size(op_obj);  // error:  no matching function for call to ‘UHDM::ExprEval::size(const any*&)’
...

The function expects const any *, but it's being interpreted as a const any *&. Is there a way to rid the reference here?

Thanks a lot!

alaindargelas commented 1 year ago

You are missing quite a few arguments to the method call UHDM::ExprEval::size: https://github.com/chipsalliance/UHDM/blob/785fb0052bdd70362f62ca23fc8e128a95678673/templates/ExprEval.h#L60

You need to pass it a context (Where you are in the elab tree for instance), your visitor needs to pass that info.

mysoreanoop commented 1 year ago

Oh right, sorry I wasn't thinking. It seems to be working, but sometimes incorrectly, thanks!

For example, when there's a case condition which is an input logic [2:0], it seems to be printing 1 always (instead of 3). And, when a condition is a logic enum [2:0] {...} state, for example, it's printing 0 (incorrect).