-
Notifications
You must be signed in to change notification settings - Fork 52
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
Create an AXI-interface generator implemented Calyx #1733
Comments
Excellent! Sounds like a plan! |
Expanding a little bit on the imaginary code I wrote above for how the AXI "wrapper" code might work, I think we should really use Calyx's That is, imagine that we have our main Calyx design, called
We should first rewrite
(In fact, we have elsewhere occasionally discussed getting rid of the Then, our job in this work is to generate a new top-level component, called
The control for
Therefore, we can think of
…which can hopefully be implemented as a big (One minor note: the |
I like this idea! It is in the spirit of #1603. The idea is that Calyx is purely responsible for defining the computational interface of the component and something else can come in and provide the memory interface. Spitballing a little more: one can imagine that once we #1261 and have a standard memory interface that has read and write |
One question I have here is how to AXI interfaces will be implemented. I know currently the AXI interfaces reads all inputs values to on-chip memory and then launches the kernel. My general suggestion is that by default external memories should be fully off-chip, aka every time we want to read an address value we need to use the AXI interface to read a value from DRAM. If we want to buffer values on chip, this should be explicitly in the Calyx somewhere (either the main module or the axi wrapper module). |
Yeah, seconded! The goal of this project (if I understand correctly) is to express as much of the logic needed to move data around within Calyx itself. This includes the logic needed to "externalize" memory interfaces. |
Thanks for the feedback, both of y'all!
Yes, it is in scope in our original proposal to go beyond the "one-sized-fits-all" data flow we have now. That is, aside from just changing the default (from buffer-everything to buffer-nothing/directly access host memory), it seems like there are many intermediate points you'd want to generate. For example, streaming data "blockwise" instead of requesting it on demand "wordwise" would be in scope, and would put things like AXI bursts behind the So anyway, the overall trajectory here is (1) recreate exactly what we currently have (the buffer-everything-on-chip policy) in Calyx land, and then (2) use our new, awesome, flexible, hackable, debuggable AXI generator to add new features/interface styles. |
Fly-by comment but there is something unsaid about the expressive power of |
There has been substantial progress with getting the read portion of the AXI interface to work #1820. |
Given @nathanielnrn's awesome recent progress in #1842, I found myself mapping out a few granular steps for the medium-term future (aside from the aforementioned next step of converting this fixed-function implementation into a suitably parameterized generator). In no particular order:
And there are three "offshoot" ideas that are not that important but are kind of adjacent, to consider retuning to "someday":
|
As the semester is coming up I thought it seemed like a good place to stop and more concretely consider next steps and take stock of where we are with things. Some good progress has been made w.r.t creating a parameterized version of our AXI implementation:
Things left to be done for the parameterized generator:
It should be noted that all 4 of the above are blocked by #1850, which is what I will be working on most immediately. Once the generator is done, I think it makes sense to tackle things in the following order (see comment for more detail about specific tasks):
The current offshoot ideas that are adjacent to this work, that we can continue returning to someday are:
The tracking for these has been updated above. |
This all sounds great!!! Just one small note on the compiler hacking:
The heart of the matter here may not actually be a new pass, nor even a new backend: I think all we need is a compiler option that omits the |
This issue is intended to track progress on Phase 2 of Calyx Meets the Real World. This writeup gives great overarching context and what we are working towards.
Currently, we can run a limited number of programs on real FPGAS using fud. We accomplish this by generating Verilog AXI wrappers.
Unfortunately, the current state of the AXI wrappers is less than ideal. Lots of the generation code is hardcoded, and in general Verilog is not a fun language to work with. To that end, we are trying to build a generator that will take in a
.yxi
file and output an AXI interface -- in calyx. The hope is that by usingcalyx-py
we will be able to avoid some of the issues we've faced in the past (see #1071) and more easily create a more generalizable wrapper.For reference, a
dot-product.yxi
(meaning the yxi-backend output of adot-product.futil
program) looks like this:The current plan is to have a separate AXI controller for each memory, similar to the current Verilog implementation.
Currently, both @evanmwilliams and I are working on getting acquainted with
calyx-py.
After that it probably makes sense to get together and formalize some next incremental steps, as a full AXI interface seems a bit daunting to tackle all in one go.At that point we can list and track completion of subtasks here!
Update Nov 20 2023:
Both me and @evanmwilliams have familiarized ourselves with
calyx-py
a bit. Work has also gone into manually creating a version of a Calyx axi-wrapper. Based on in person discussions it seems like next step is to create a testbench that ensures the correctness of said axi-wrapper with cocotb, similar to what we've done in the past. Goal is to strat with just the read portion of an axi-wrapper. The code we are trying to target lives in the branchaxi-calyx-gen
Update Jan 2024:
I've broken up work into a bunch of smaller tasks both in case we onboard someone to help work on this and also to give a clear game plan as we all get busy as the semester starts. There is a lot here but I think by chipping away at things we can make good progress.
Tasks to be completed, in order:
AR
andR
channels) implemented in Calyx. This a way to better understand what we hope to eventually dynamically generate.Multiple assignments to port
issue due to simulatedx
s #1801 for current blocker.AW
,W
, andB
channels) implemented in Calyx. This will hopefully be more straightforward once the infrastructure is set up from tasks above.calyx-py
AXI generator write channel #1861calyx-py
AXI generatorbresp
channel #1862external-to-ref
pass #1918fud2
path #1994fud2
path #1994yxi
file. Introduce calyx -> axi-wrapped-calyxfud2
path #1994yxi
backend to look forref
memories in addition to@external
memories #1932yxi
spec. Introduce calyx -> axi-wrapped-calyxfud2
path #1994fud2
path #1997calyx-py
AXI wrappercocotb
testbench acceptyxi
interfaces and dynamic input data #1938 Introduce verilog -> cocotb simulationfud2
path #1997a passan option to the relevant compiler pass that omits the go/done interface and replaces it with an ap_start/ap_done interface for toplevel components. This will likely be necessary for XRT interfacing to work. It is worth noting that there may be another option to target user-managed control instead, but it seems like this misses some of the point of creating generalizable interface for FPGAs that give us the benefits of using XRT.Some offshoot ideas that have sprung up:
IDX_SIZE
information to .yxi outputs. #1751, but it seems like we are moving in a direction that requires memories to be well-formed in the sense that IDX_SIZE must match the expected width based on SIZE of a memory and that multi-dimension memories be flattened to seq_mem_d1 memories.The text was updated successfully, but these errors were encountered: