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

[LLHD][Arc] Indexing and slicing lowering from Verilog to LLVM IR #8065

Open
AndreyVV-100 opened this issue Jan 10, 2025 · 3 comments
Open

Comments

@AndreyVV-100
Copy link
Contributor

Hi! I'm trying to use circt for lowering to LLVM IR. I found such a construction in some example:

module Mod (input clk, input a, input b, output logic[1:0] c);
always_ff @(posedge clk) begin
    c[0] <= a;
    c[1] <= b;
end
endmodule

I used this pipeline:

circt-verilog ranges.sv | circt-opt --llhd-early-code-motion --llhd-temporal-code-motion --llhd-desequentialize --llhd-sig2reg --canonicalize | arcilator

But I got error body contains non-pure operation in arcilator. Also I had same error when I tried to use slicing instead of indexing. What needs to be done to run arcilator successfully?

@maerhart
Copy link
Member

Hi @AndreyVV-100
The reason that Arcilator bails out here (with a not very helpful error message to be fair), is that here are llhd.sig.extract ops left (coming from the indexing/slicing) which hinder llhd-sig2reg in promoting the llhd.prb and llhd.drv operations which are the non-pure ops arcilator complains about. They need explicit support in arcilator (and need some event-queue based approach in the general case) which we don't have yet.

To work around this, SROA can be run before sig2reg but only structs and arrays are supported upstream yet. I have a prototype branch with some limited integer support that should be enough for your case here in case you want to try it out: https://github.com/maerhart/circt/tree/mix-and-match

I hope I'll find the time to upstream that sometime soon.

@AndreyVV-100
Copy link
Contributor Author

Hi @maerhart! Thank you for the answer! I tried mix-and-match branch, it works for this case but slicing isn't working yet.

module Mod (input clk, input a, input b, output logic[3:0] c);
  always_ff @(posedge clk) begin
     c[1:0] = {a, b};
  end
endmodule

Is it planned to be supported by SROA or arcilator? Can it be made by bit blasting? If so, I can try to patch your branch.

@maerhart
Copy link
Member

Yes, I restricted the SROA bit blasting the case when only individual bits are accessed. It would also work for slices, but it's not an optimal solution if the slice offset is known statically (since you'd only need to cut the original integer at the start and endpoint of the slice). For dynamic slices, we'd need to cut at all possible start at endpoints which will almost bit blast the entire integer if the slice is short, so it'd be fine there. If the slice is almost as big as the original integer, though, we could also do quite a lot better than just bit blasting.

Implementing this more optimal strategy will probably require a dedicated pass that does some analysis to figure out these cut points, but having a simple bit blasing implementation that we can improve upon later would also be quite nice 😄

You'd also need to add support for slices to the ResolveDynamicSignalAliases pass there to get it working E2E (because SROA only supports static indices).

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

No branches or pull requests

2 participants