-
Notifications
You must be signed in to change notification settings - Fork 53
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
[xilinx] Use a single AXI interface to communicate with all memories #853
Comments
From the perspective of a Calyx user, it seems the onus is on the backend to ensure this constraint is met? |
Ah, yes! To clarify, that's the intent in this issue: to make the |
@sampsyo did you get a chance to see what happens if you just delete the XML lines that instantiate the |
Just following up based on a synchronous conversation, for posterity: although it could be interesting, I didn't end up trying this at the time because I believe it would need to be a coordinated change between the XML and the Verilog that implements the AXI interfaces. I worried I would just trigger more inscrutable errors by creating a misalignment between the signals in the Verilog and the declared AXI interfaces that refer to them. |
An alternative explanation that I need to investigate: it looks like we redundantly declare the AXI interfaces in the Tcl script that produces So maybe we can keep the multi-interface style but just properly hook them up in the |
I'm not sure if the "redundancy" is referring to the fact that they are essentially doing the same thing for |
Ah, no, what I meant was that these lines seem to be redundant with what we do in |
In response to @yn224's comment at #876 (comment): Great! This is such a relief!! It should be so much easier to address this way than by multiplexing multiple memories on a single AXI bus. My suggestion for a next step is to put a Tcl …can just pass all the names of the AXI interfaces after ipx::associate_bus_interfaces -busif $busname -clock ap_clk [ipx::current_core] Let's do that first! @yn224, can you give that a shot and make a PR? In this initial version, we can hard-code the fud support to just pass Of course, the next step will be to figure out how to get that list of AXI interface names. We will either have to change the Calyx compiler to dump a list, or we can parse the XML it already generates to get the list. |
Using Vivado/Vitis to compile many Calyx-generated Verilog programs currently produces this totally inscrutable error, first reported by @yn224:
I did a lot of digging around into the generated Tcl from which this error arises. It appears that the problem comes up when the design has multiple AXI interfaces, which happens for multiple
@external
Calyx memory declarations. You can see this by comparing these programs:The
dot-product
example has three external memories, whilelanguage-tutorial-iterate
has only one. And only the former triggers the problem.The solution will be to multiplex all the memories on a single AXI port. The memories will just be mapped into different address ranges on the same, general port. Here’s where we declare one AXI port per memory:
https://github.com/cucapra/calyx/blob/9d02b33c03ac5b96bde1b930c515a095bb7c0ad3/src/backend/xilinx/xml.rs#L149-L156
We will also need to change the Verilog generation for the AXI interfaces to use a single port, somewhere around here:
https://github.com/cucapra/calyx/blob/9d02b33c03ac5b96bde1b930c515a095bb7c0ad3/src/backend/xilinx/memory_axi.rs#L27
It would also be good to set up some automated (Runt-based) testing of the whole Xilinx toolchain thing so we don’t break stuff while trying to change this.
Details about the debugging process, for posterity & the morbidly curious
The error arose from
dr.bd.tcl
, which I got from therunme.log
referenced in the error. This is the Tcl script that Vivado generates according tokernel.xml
, the file we generate that describes the interface to the RTL blob. The XML file contains directives like this describing AXI interfaces:(This is a snippet from the XML we generate for
dot-product.futil
, FWIW.) As you can see, there are four AXI ports for three memories: one is a control port. Then, there are threearg
declarations for the externalized memories in the Calyx program (and a timeout argument also).These AXI
port
declarations get translated tohbm_memory_subsystem::map_memory_resource
calls in the Vivado-generated Tcl. I noticed that the error was coming from the second one, i.e., the call form1_axi
. I got curious and compared this against the XML for one of the examples that comes with the Vitis RTL kernel tutorials. Once packaged up, thatkernel.xml
looks different:Namely, while there are still several
arg
declarations, they all use a single AXI port:m_axi_gmem
. They just use different offsets within it.That’s when I formed the hypothesis that the Xilinx toolchain just doesn’t support multiple full-sized AXI ports. I validated this hypothesis by trying a different example program with a single external memory, which turned out to be
language-tutorial-iterate.futil
, referenced above.The text was updated successfully, but these errors were encountered: