-
Notifications
You must be signed in to change notification settings - Fork 298
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
[PipelineToHW] Rework hardware lowering #5234
Conversation
74b0c35
to
5072355
Compare
5072355
to
3c688ab
Compare
Just curious, what is the motivation for the outlined lowering? It seems this is what motivated the new |
Certain RTL compilers only do resource reporting at the module granularity. Users often want to have resource usage information at the stage granularity. |
3c688ab
to
b4b701d
Compare
This signal is intended to connect to all stages within the pipeline, and is used to stall the entirety of the pipeline. It is lowering defined how stages choose to use this signal, although in the common case, a `stall` signal would typically connect to the clock-enable input of the stage-separating registers. Future PRs will implement hardware lowerings - blocked by #5234.
89e5c4c
to
be20f7e
Compare
b4b701d
to
0d88451
Compare
This PR reworks hardware lowering to be based on the new `pipeline.stage` operation introduced in #5246. Two lowering options are available, inline and outline lowering. Given an input: ```mlir hw.module @testMultiple(%arg0 : i32, %arg1 : i32, %go : i1, %clk : i1, %rst : i1) -> (out: i32) { %0 = pipeline.pipeline(%arg0, %arg1, %go) clock %clk reset %rst : (i32, i32, i1) -> i32 { ^bb0(%arg0_0: i32, %arg1_1: i32, %arg2: i1): %output, %valid = pipeline.stage ins %arg0_0, %arg1_1 enable %arg2 : (i32, i32) -> (i32) { ^bb0(%arg3: i32, %arg4: i32, %arg5: i1): %2 = comb.add %arg3, %arg4 : i32 pipeline.stage.return regs %2 valid %arg5 : (i32) } pipeline.return %output valid %valid : i32 } %1 = pipeline.pipeline(%0, %0, %go) clock %clk reset %rst : (i32, i32, i1) -> i32 { ^bb0(%arg0_0: i32, %arg1_1: i32, %arg2: i1): %output, %valid = pipeline.stage ins %arg0_0, %arg1_1 enable %arg2 : (i32, i32) -> (i32) { ^bb0(%arg3: i32, %arg4: i32, %arg5: i1): %2 = comb.add %arg3, %arg4 : i32 pipeline.stage.return regs %2 valid %arg5 : (i32) } pipeline.return %output valid %valid : i32 } hw.output %1 : i32 } ``` All operations are inlined directly into the parent scope of the `pipeline.pipeline`: ```mlir hw.module @testMultiple(%arg0: i32, %arg1: i32, %go: i1, %clk: i1, %rst: i1) -> (out: i32) { %0 = comb.add %arg0, %arg1 : i32 %p0_s0_reg0 = seq.compreg %0, %clk : i32 %p0_s0_valid = seq.compreg %go, %clk : i1 %1 = comb.add %p0_s0_reg0, %p0_s0_reg0 : i32 %p1_s0_reg0 = seq.compreg %1, %clk : i32 %p1_s0_valid = seq.compreg %go, %clk : i1 hw.output %p1_s0_reg0 : i32 } ``` All stages and the pipeline itself are outlined into separate modules. The pipeline will contain instantiations of the stages of which it is comprised. There will be a single instantiation of the pipeline module at the `pipeline.pipeline` location. ```mlir hw.module @testMultiple_p0(%in0: i32, %in1: i32, %in2: i1, %clk: i1, %rst: i1) -> (out0: i32) { %testMultiple_p0_s0.out0, %testMultiple_p0_s0.valid = hw.instance "testMultiple_p0_s0" @testMultiple_p0_s0(in0: %in0: i32, in1: %in1: i32, enable: %in2: i1, clk: %clk: i1, rst: %rst: i1) -> (out0: i32, valid: i1) hw.output %testMultiple_p0_s0.out0 : i32 } hw.module @testMultiple_p0_s0(%in0: i32, %in1: i32, %enable: i1, %clk: i1, %rst: i1) -> (out0: i32, valid: i1) { %0 = comb.add %in0, %in1 : i32 %s0_reg0 = seq.compreg %0, %clk : i32 %s0_valid = seq.compreg %enable, %clk : i1 hw.output %s0_reg0, %s0_valid : i32, i1 } hw.module @testMultiple_p1(%in0: i32, %in1: i32, %in2: i1, %clk: i1, %rst: i1) -> (out0: i32) { %testMultiple_p1_s0.out0, %testMultiple_p1_s0.valid = hw.instance "testMultiple_p1_s0" @testMultiple_p1_s0(in0: %in0: i32, in1: %in1: i32, enable: %in2: i1, clk: %clk: i1, rst: %rst: i1) -> (out0: i32, valid: i1) hw.output %testMultiple_p1_s0.out0 : i32 } hw.module @testMultiple_p1_s0(%in0: i32, %in1: i32, %enable: i1, %clk: i1, %rst: i1) -> (out0: i32, valid: i1) { %0 = comb.add %in0, %in1 : i32 %s0_reg0 = seq.compreg %0, %clk : i32 %s0_valid = seq.compreg %enable, %clk : i1 hw.output %s0_reg0, %s0_valid : i32, i1 } hw.module @testMultiple(%arg0: i32, %arg1: i32, %go: i1, %clk: i1, %rst: i1) -> (out: i32) { %testMultiple_p0.out0 = hw.instance "testMultiple_p0" @testMultiple_p0(in0: %arg0: i32, in1: %arg1: i32, in2: %go: i1, clk: %clk: i1, rst: %rst: i1) -> (out0: i32) %testMultiple_p1.out0 = hw.instance "testMultiple_p1" @testMultiple_p1(in0: %testMultiple_p0.out0: i32, in1: %testMultiple_p0.out0: i32, in2: %go: i1, clk: %clk: i1, rst: %rst: i1) -> (out0: i32) hw.output %testMultiple_p1.out0 : i32 } ```
0d88451
to
d09e2db
Compare
I will preemptively merge this and then schedule a post-merge review, seeing as @teqdruid most likely is going to need this today. |
This signal is intended to connect to all stages within the pipeline, and is used to stall the entirety of the pipeline. It is lowering defined how stages choose to use this signal, although in the common case, a `stall` signal would typically connect to the clock-enable input of the stage-separating registers. Future PRs will implement hardware lowerings - blocked by #5234.
This PR reworks hardware lowering to be based on the new
pipeline.stage
operation introduced in #5246.Two lowering options are available, inline and outline lowering.
Given an input:
Inline lowering
All operations are inlined directly into the parent scope of the
pipeline.pipeline
:Outline lowering
All stages and the pipeline itself are outlined into separate modules. The pipeline will contain instantiations of the stages of which it is comprised. There will be a single instantiation of the pipeline module at the
pipeline.pipeline
location.