Skip to content
This repository has been archived by the owner on Mar 29, 2024. It is now read-only.

Consider higher-level abstractions for signed/unsigned signals #7

Open
yupferris opened this issue Aug 31, 2020 · 0 comments
Open

Consider higher-level abstractions for signed/unsigned signals #7

yupferris opened this issue Aug 31, 2020 · 0 comments

Comments

@yupferris
Copy link
Owner

yupferris commented Aug 31, 2020

Currently all Signals are assumed to be unsigned buckets of bits, and signed-ness only really exists for some operations where it will actually produce a different result (eg mul vs mul_signed). While I believe this is good for the graph API in general (since the compilers/code generators don't ever have to care about it), it leaves some possible useful explicitness in user code and error checking on the table.

For example, one idea I've had in my head for a long time now is to augment the API with higher-level Int/UInt (or similar) constructs that would be normal rust structs containing a Signal, but would represent signed-ness in rust's type system. All operators and other API entry points that exist on Signal today would then be exposed on the higher-level constructs as well, so a user would typically use those where they use Signal today. Operators like Mul would be implemented by using mul for UInt and mul_signed for Int transparently, and rust's type system would catch errors if, for example, a user tried to multiply a signed signal (Int) with an unsigned one (UInt). Explicit cast operators can also be added for these types to explicitly change between them (possibly in the form of From impls, so a user could use .into() just like they would with other rust types).

This is potentially a lot of work and testing overhead so I haven't jumped in, but I wanted to document somewhere as I think it's ultimately useful.

This could perhaps be an opt-in feature for the lib as well, in case a user doesn't care and wants to use Signals directly (which I think should always be allowed anyways).

Some unresolved things:

  • How should Mem and Module input/output APIs change? Ideally a user wants to create eg. a Mem with signed elements, and that should be specified somehow. Perhaps UIntMem or IntMem or similar? The same goes for Module inputs/outputs, where a user wants a given input to only accept signed/unsigned signals.
  • How should module inputs/outputs change? Should they use signed types?
  • Should signed signals propagate signed values to tracing? Can this be used in relevant formats?
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant