Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTL pass fail to tell value used is constant #271

Open
KelvinChung2000 opened this issue Mar 28, 2024 · 6 comments
Open

RTL pass fail to tell value used is constant #271

KelvinChung2000 opened this issue Mar 28, 2024 · 6 comments

Comments

@KelvinChung2000
Copy link

The VerilogTranslationPass fail to tell the value used is a constant.

from pymtl3 import *
from pymtl3.passes.backends.verilog import *


class test(Component):
    def construct(s, n):

        s.in_ = InPort(mk_bits(5))
        s.a = Wire(4)

        @update
        def testTrunc():
            s.a @= trunc(s.in_, clog2(n))


if __name__ == "__main__":
    m = test(16)
    m.elaborate()
    m.set_metadata(VerilogTranslationPass.enable, True)
    m.apply(VerilogTranslationPass())

will produce the following error

In file /home/kelvin/pymtl3/trucTranslationFail.py, Line 13, Col 18:
  s.a @= trunc(s.in_, clog2(n))
        ^
- the 2nd argument of trunc {nbits} is not a constant int or BitsN type!

I can fix the problem by doing the following

        t = clog2(n)
        @update
        def testTrunc():
            s.a @= trunc(s.in_, t)

But it is more intuitive to do it the first way.

@cbatten
Copy link
Contributor

cbatten commented Mar 28, 2024

hmmm ... what would the ideal Verilog be though? Should we turn clog2 into $clog2 in the Verilog?

@KelvinChung2000
Copy link
Author

Or try to evaluate the expression, replace it with a constant int value, and catch it only when the evaluated result is not int. To aid readability, we can add a comment next to the evaluated number to indicate this is coming from an evaluated expression.

@cbatten
Copy link
Contributor

cbatten commented Mar 28, 2024

Interesting idea! I don't think we do any of that currently ... we don't do any kind of constant evaluation during translation ... it is very much a source-to-source transpilation process ...

@KelvinChung2000
Copy link
Author

If this is fully implemented, one main advantage would be that more native constructs like dict, list, and enum can be used while writing the hardware design, then evaluating them if they end up as a constant or potentially InPort/OutPort then we move forward with the compilation process, like for x, y in a.items() which I don't think is possible at the moment. But I am also unsure how useful this would be when writing hardware.

A simple case use I can think of is we can convert the following

a = [CompnentA, CompnentB, CompnentB]
for x in range(len(a)):
  a[x].in_ ...

to

a = [CompnentA, CompnentB, CompnentB]
for x in a:
  x.in_ ...

@cbatten
Copy link
Contributor

cbatten commented Mar 28, 2024

But to be clear you can definitely do what you are showing above at elaboration time outside an update block ... you just cannot do it in an update block ... this idea of partial evaluation during translation of an update block seems like an interest research direction!

@yo96
Copy link
Contributor

yo96 commented Mar 28, 2024

We definitely have some degree of partial evaluation during the translation pass. For example, the free variable t is evaluated at the translation time and will be translated into a constant. We made a decision not to support arbitrary function calls (except for the built-in functions) because it could lead to a whole bunch of corner cases and would require a significantly more complex analysis. While it is technically feasible to add special support for specific functions like clog2, we believe that maintaining consistency and avoiding confusion by not supporting function calls altogether is a more prudent approach.

Again, like Chris mentioned above, you can totally use any Python constructs or advanced syntaxes for structural composition outside the update block.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants