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

Create IDL Backend #1729

Merged
merged 16 commits into from
Oct 10, 2023
Merged

Create IDL Backend #1729

merged 16 commits into from
Oct 10, 2023

Conversation

nathanielnrn
Copy link
Contributor

@nathanielnrn nathanielnrn commented Sep 25, 2023

This PR creates a basic backend which takes in a calyx program and outputs information about the program's top level memories.
This is in the name of working on #1105 and #1603.

Specifically, for calyx programs like this

component main() -> () {
  cells {
    @external(1) A0 = std_mem_d1(32,8,4);                                                                                                                                                       
    @external(1) B0 = std_mem_d1(32,8,4);
  }
  ...
}

This backend produces

{
  "toplevel_name": "main",
  "memories": [
    {
      "name": "A0",
      "width": 32,
      "size": 8
    },
    {
      "name": "B0",
      "width": 32,
      "size": 8
    } 
  ]
}

A few things to note that probably warrant further discussion:

  1. Currently this only reports on mem cells marked with @external. That may be all we need for interfacing with our programs via AXI?
  2. Related to above, need to better understand our *memh goals and what *memh even does to understand what information we will need.
  3. For multi-dimensional memories, this backend currently squashes the dimensions and outputs the product of each dimension's size as size. Would it be useful to retain that information instead?
  4. Naming and location: Should probably rename this. Maybe CIDL? Also, this doesn't belong in xilinx/ but I'm hoping to get this out tonight for some early feedback and I still struggle with rust module/hierarchy issues, so will address later.

EDIT
Some answers to the above after a synch discussion:

  1. Seems okay to march forward with only @external memories. Furthermore, only examining the toplevel memories that are external is okay, as marking memories that are parts of subcomponents in a calyx program is a bit messy and probably shouldn't be valid in the first place.
  2. Basically, we want default calyx to only produce things that are synthesizable, which *memh is not. Our wrapper will wire up these *memh calls as needed to enable simulation.
  3. This seems fine for now, as this corresponds with verilog representation of memories.
  4. YXI is our name of choice. Will have .yxi file extensions and should be moved up a directory.

Some open questions:
Naming and placement. This is probably not xilinx specific so should be
moved up a level into just src. Also, naming is generic and not good and
should be changed

TODO: Only works withs d1 memories, but should not be hard to alter
Previously could only handle 1 dimension mems.
NOTE: This flattens dimensions into a single size variable that is spit
out. However it may be useful to maintain info about shape of memory?
Need to think about this more
Copy link
Contributor

@sampsyo sampsyo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good overall! I think my main substantive comment in here is that there are a few pre-existing utility functions that would probably benefit from being moved to their own file so they can be shared between the different backends that use them (to avoid copying-and-pasting the code for the utility functions).

@@ -18,6 +18,7 @@ string-interner.workspace = true
itertools.workspace = true
linked-hash-map.workspace = true
serde = { workspace = true }
serde_json.workspace = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ignorant enough of Rust workspace setups to not exactly know the difference between using serde_json.workspace = true here vs. just doing this right here:

serde_json = "1.0"

…and omitting this from the workspace-global Cargo.toml. Presumably there is a difference but I'm not sure what it is! Maybe this is the right thing; just thought I'd double-check this was the intended strategy (vs. what we do for csv and vast below).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe @rachitnigam has an opinion on this? Tbh I've just been pattern matching from stuff I've seen around, the details of these workspaces elude me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably doesn't matter much! I guess the upside of what you have now is that anyone else in the tree who ends up needing serde_json will use the same version.

calyx-backend/src/backend_opt.rs Outdated Show resolved Hide resolved
calyx-backend/src/xilinx/idl.rs Outdated Show resolved Hide resolved
calyx-backend/src/xilinx/idl.rs Outdated Show resolved Hide resolved
calyx-backend/src/xilinx/idl.rs Outdated Show resolved Hide resolved
calyx-backend/src/xilinx/idl.rs Outdated Show resolved Hide resolved
calyx-backend/src/xilinx/idl.rs Outdated Show resolved Hide resolved
}

// Returns Vec<String> of memory names
fn external_memories(comp: &ir::Component) -> Vec<String> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like external_memories is identical to the definition in top-level.rs. (And get_mem_info is similar but does the "size flattening" thing internally?) What do you think about moving this stuff to a common utility file so both backends can use it, to avoid the duplication of code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully this is better now? @sampsyo for visibility.

tests/backend/idl/dot-product.futil Outdated Show resolved Hide resolved
Moved things into calyx-ir/utils. Things like get_mem_info and functions
that get memories marked as external, along with their names
@nathanielnrn nathanielnrn force-pushed the mem-interface-backend branch from 6814c63 to e04c1e7 Compare October 7, 2023 04:40
Copy link
Contributor

@sampsyo sampsyo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wahoo! Looks great!! Go ahead and hit that green button whenever you are ready. 😃

@rachitnigam
Copy link
Contributor

@nathanielnrn let's get this merged if everything looks good!

@nathanielnrn nathanielnrn merged commit 062b9a8 into master Oct 10, 2023
5 checks passed
@nathanielnrn nathanielnrn deleted the mem-interface-backend branch October 10, 2023 16:12
rachitnigam pushed a commit that referenced this pull request Feb 16, 2024
* WIP, add to backend options

* add serde_json dependency for IDL backend

* WIP work on IDL

* Minimal working version of IDL generator

Some open questions:
Naming and placement. This is probably not xilinx specific so should be
moved up a level into just src. Also, naming is generic and not good and
should be changed

TODO: Only works withs d1 memories, but should not be hard to alter

* Let IDL generator handle multi-dim mems

Previously could only handle 1 dimension mems.
NOTE: This flattens dimensions into a single size variable that is spit
out. However it may be useful to maintain info about shape of memory?
Need to think about this more

* add basic runt tests

* clippy formatting

* rename idl to yxi and make serde_json call shorter

* add error conversion for serde_json for yxi backend

* update runt tests for yxi

* update cargo lock with serde_json

* formatting

* move yxi up a directory

* WIP of extracting utility functions

* Refactor toplevel and yxi util functions

Moved things into calyx-ir/utils. Things like get_mem_info and functions
that get memories marked as external, along with their names

* clippy and formatting
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants