-
Notifications
You must be signed in to change notification settings - Fork 50
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
Calyx wrapper for Berkeley HardFloat Verilog library #1928
base: calyx-float
Are you sure you want to change the base?
Conversation
Woo! Awesome! This is exactly what I had in mind as well! Couple of things:
|
Just opened up
Agree. Yes
Sounds good! So we start with first extending the existing parser? |
Hi @rachitnigam ! Just want to share an update that the current wrapper can perform floating add/sub and multiplication! So I think I can move on to extending the user input data type to conduct more thorough tests. Any thoughts or tips on initiating and streamlining this process? Thanks! |
User inputs seem like the right next step. Do you want to create a plan to scope out the work in this PR? For example one primitive plus fud extension should be enough |
Sure! What does "fud extension" mean here, fud numeric type extension for floating-point values? And do you agree that Calyx users will only use normal floating-point values, and at most, they will use IEEE format representation, and that they barely want to interact with HardFloat specific formats like "recoded" formats and "raw deconstructions"? If that's the case, then I think ideally, I'd start with Now I only have
If we indeed want an |
Hi @rachitnigam , I think I have some idea about how to proceed! Can you check my plan to see if it makes sense?
|
Hi @jiahanxie353, I'm traveling a lot this month so I'll recommend that you go ahead and try things out instead of waiting on my responses. Folks in the Calyx zulip and slack should also be able to help. |
Sure thing, sounds good! |
Hi @rachitnigam , just finished a milestone that we can support passing floating point values in json and perform two floating-point numbers addition when using fud! |
primitives/float/addFN.futil
Outdated
@@ -0,0 +1,16 @@ | |||
extern "addFN.sv" { | |||
primitive addFN[ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this implemented combinationally? If so, we should mark it as a comb primitive
instead of primitive
. Also, we should probably not implement this as a combinational primitive at all since that is unlikely to meet timing?
Looks cool! Couple of notes:
|
Yeah we definitely want floating point units to be pipelined when used in real designs. I think berkeley hardfloat is all combinational? If that's the case we can maybe add registers at the beginning and/or end and hope that retiming will do a decent job. In Vitis HLS all the floating point units I've seen are between 3 and 5 stage pipelines. I think this is definitely another case where allowing the latency to be parameterized would be very helpful. |
@jiahanxie353 I think the move is to pipeline the output value of the adder by 4 cycles for now. Once we have a set of primitives and some designs, we can push them through the FPGA flow and see if designs are correctly being mapped onto DSPs on the FPGA (which are hardened blocks for efficiently performing operations likes add and mult). Once this change is done, I think you're good to merge! Next step would be to change |
Excellent. I'm late to the party, but I agree with where everything has ended up: namely, @jiahanxie353, your plan enumerated above sounds right to me, and @rachitnigam's suggested next steps (test inputs from data files, and a fixed 4-cycle latency) are also the right things to do here. To expand in a possibly-unnecessary way about the 4-cycle latency: basically, the idea in Berkeley HardFloat is that all the operations are provided as combinational logic, but realistic designs do not want combinational FP ops. So its intended use case is that people just stick "useless" registers in front of or behind the HardFloat operation, and the EDA toolchain does its best to perform retiming (magically transforming the combinational-plus-registers description into a proper, balanced pipeline). So one option would be to expose these as |
One extra category of logistical discussion:
|
66504c2
to
dd3ca25
Compare
Thanks for all the advice folks! Got a 4-cycle adder by using dummy registers. As per
I believe you are right. That's why I kept
in the source files like here for attribution. Is there anything else I need to do for copyright?
It'll probably be annoying to adapt to upstream changes in the future if we just use a static snapshot. The issue is that HardFloat is implemented in Chisel in their repo. Implementing a translator/transpiler from Chisel to Verilog could (?) solve the concern but I doubt it's worth the effort. And since there's no direct Verilog implementation, I believe people just use the Verilog files obtained from a zip file in this page. |
This all sounds good! One extremely tangential note: "transpiler" is not a meaningful term: https://rachit.pl/post/transpiler/ Chisel already has a compiler to Verilog. |
Got it; thanks, @jiahanxie353! Here's my suggestion about how to deal with including external source code like this. I think we have two options:
Anyway, I think either could work! Just wanted to lay out the options. |
Got it, I'll take the second fetch-and-unzip approach! While working on it, got a decision to make regarding (1) changing the HardFloat source code after fetching it; (2) modifying
Do you have any preference over 2 options? |
I see! Good question… do you think you could elaborate a tiny bit more on the problem that each of these changes would solve? Here is my guess, but I am low-confidence: The way (most? all?) Calyx primitives currently work is that the Verilog code for each primitive gets inlined into the generated Verilog code. The result is an entirely self-contained Verilog program, consisting of both primitive code and Calyx-compiled code, that we can compile all by itself. HardFloat presents another level of logistical complexity because, of course, we need to include a bunch of external files. The current solution is that our calyx/primitives/float/addFN.sv Lines 4 to 6 in ebd2069
This in turn requires the actual HardFloat source files to use the same path prefix to
Obviously, the "pristine" HardFloat source files don't know about the path
…and that doesn't necessary work by default to include the file relative to the containing source file, for some reason. I don't understand Verilog!!! It seems like it should just work! It is annoying that it doesn't!!!!!!!
Is that a correct summary of the situation? If so, just adding the flag seems way easier to me… clearly, there is more we should do around the problem of Calyx now not emitting self-contained Verilog (it now has |
Yes, that's pretty much the situation and Firstly, the "pristine" HardFloat has this wacky kind of import: Even if they intended to mean relative import, they should at least write:
But anyhow, this is not difficult to solve. And my proposed solution is to append Line 109 in 4bc3007
A trickier thing seems unsolvable by using
This line is manually inserted by me, and there's no such import in the "pristine" HardFloat. And in fact, there's no single file that has As a workaround, |
I haven't kept track of this thread that well but one thing that would be good to have is being able to have a default flow that generates exactly one Verilog file like we do today. We can emit some information information the user that they've requested that we link with HardFloat and therefore are implicitly agreeing to its LICENSE. We also should be carefully when we provide a new release on crates.io if we place Hardfloat in |
…e test case and use *.data to input values
…nclude and library files include for iverilog
…ging their config toml
…t part select out of order
@jiahanxie353 with the new FP changes, seems like we'd want to merge this relatively soon. I think we should split this into two PRs: one that adds support for |
Sounds good, I'll do that! |
Implement a wrapper in Calyx for Berkeley HardFloat
fNToRecFN
(IEEE standard format to HardFloat recoded format) Verilog module (adopted based on PyMTL's corresponding file).And include a corresponding test case to convert from standard format to recoded format when the input floating-point number is a normal number.
I want to first create a draft PR to make sure that I'm on the right track. And I will include more test cases, such as subnormals, NaNs; and work on other HardFloat modules.