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

Explicit casting proposal #111

Closed
rachitnigam opened this issue Mar 3, 2019 · 3 comments
Closed

Explicit casting proposal #111

rachitnigam opened this issue Mar 3, 2019 · 3 comments
Labels
Discussion Needed Language features that need more discussion before implementation

Comments

@rachitnigam
Copy link
Member

@sa2257 brought up some concerns in #53 and #102. I think his high level point is about the control over bitwidth specifications. The language already allows for let binders to specify their explicit types. However, the automatic casting of variables might not be desirable:

let m : bit<10> = 10; // m is bit<10>
let k = 1 // k is bit<1>
let x = m + k; // x is bit<10>

Implicitly, the type checker did the following cast:

let m : bit<10> = 10; // m is bit<10>
let k = 1 // k is bit<1>
let x = m + (k as bit<10>); // x is bit<10> 

We can add the explicit casting operator as to change the bitwidths of variables. The naive is complicated for a few reasons:

  • Unknown: If the header library ap_int doesn't allow addition of arbitrary bitwidths, casting will have to manually "move" a small bitwidth value into a larger memory:
let x = 1; // x is bit<1>
100 + (x as bit<10>)

will have to turn into:

let x: bit<1> = 1;
let x_1: bit<10> = x
100 + x_1

This will require full ANFing of all complex expressions.

  • Casting for fixed point numbers: Looking forward, fixed point numbers are defined with the number of bits for the mantissa and exponent. What does a cast from one configuration to another mean? Does the language automatically re-interpret it into a new value:
let f: fixed<4, 2> = 8.2
let f2 = (f as fixed<3, 3>) // what is the value of f2.  
  • Unsigned to signed: Should the value be reinterpreted? C does this but this is not necessarily desirable.

  • Casting down to smaller bitwidth: What should happen in this case?

@rachitnigam rachitnigam added the Discussion Needed Language features that need more discussion before implementation label Mar 3, 2019
@sampsyo
Copy link
Contributor

sampsyo commented Mar 4, 2019

Good points all. Here are some disorganized thoughts:

  • I kinda think automatic zero-extension is a good thing? It's hard to see how you'd shoot yourself in the foot with that, but I'd be interested to be proven wrong with a real-ish example of how this does something surprising.
  • That said, an explicit cast operator in addition to the explicit version certainly can't hurt! For example, this would probably be necessary for narrowing the bit width. I'm not entirely sure what semantics to use there, but keeping the least-significant bits is probably most sensible. Or we could require that you use a bit "slice" to choose exactly the bits you want, like foo[0:10] to get the 10 LSB of foo as a bit<10>.
  • I'm not too familiar with the ap_int library from Vivado, but I suspect conversion to three-argument form like that won't be necessary for code generation. Because C++ implicit conversion constructors are "just" syntactic sugar for explicit conversions, it should be possible to emit x as bit<10> as something like static_cast< ap_int<10> >(x).
  • Really good question about casts between fixed-point types. Of course, overflow will be possible when narrowing either dimension (exponent or mantissa). But it would be nice to have the assurance that when the number is representable in the new format, it does get represented correctly. If it overflows, then a simple policy that is easy to implement in hardware but might not ever be what you really want—such as overflowing both of the components separately—would probably be fine.

@kwf37
Copy link

kwf37 commented Mar 5, 2019

Here's my two cents about bit widths-

  • Zero extension seems like it would be problematic for signed arithmetic. My understanding is that typically hardware designers are explicit about zero extenders and sign extenders in hardware, so automatic zero extension seems to take away that control to me. However, if all arithmetic is unsigned then I think it is harmless.

  • For going from large bit widths to smaller, I think the programmer should specify a bit slice explicitly. I think allowing implicit bit width conversions from large bit widths to smaller ones would result in a lot of extra mistakes while designing hardware.

  • Generally a lot of my mistakes when writing Verilog is due to mixing up bit widths, so I feel shaky about the idea of automatic bit width conversions. I'd say >90% of the time I have a bit width issue it's usually due to my reasoning or typos and not intentional.

@rachitnigam
Copy link
Member Author

rachitnigam commented May 2, 2019

Fixed in #188

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Discussion Needed Language features that need more discussion before implementation
Projects
None yet
Development

No branches or pull requests

3 participants