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

[Pipeline] Add "ext" inputs to pipelines #5347

Merged
merged 6 commits into from
Jun 20, 2023

Conversation

mortbopet
Copy link
Contributor

ext inputs are inputs which are accessible in any pipeline stage, and which will never be registered during register materialization. If you imagine a pipeline as signals going from left to right with registers in between, ext inputs are inputs that hook in from the top or bottom, into any pipeline stage.

In hardware (outlined) lowering, the external inputs are only provided to stages which actually reference them:

hw.module @testSingleWithExt(%arg0: i32, %ext1: i32, %clk: i1, %rst: i1) -> (out0: i32, out1: i32) {
  %0:2 = pipeline.scheduled(%arg0, %arg0) ext (%ext1 : i32) clock %clk reset %rst : (i32, i32) -> (i32, i32) {
  ^bb0(%a0: i32, %a1 : i32, %ext0: i32):
    %true = hw.constant true
    %1 = comb.sub %a0, %a0 : i32
    pipeline.stage ^bb1 regs(%1 : i32) enable %true

  ^bb1(%6: i32):
    // Use the external value inside a stage
    %8 = comb.add %6, %ext0 : i32
    pipeline.stage ^bb2 regs(%8 : i32) enable %true
  
  ^bb2(%9 : i32):
  // Use the external value in the exit stage.
    pipeline.return %9, %ext0  : i32, i32
  }
  hw.output %0#0, %0#1 : i32, i32
}

// lowers to
  hw.module @testSingleWithExt_p0(%in0: i32, %in1: i32, %extIn0: i32, %clk: i1, %rst: i1) -> (out0: i32, out1: i32) {
    %testSingleWithExt_p0_s0.out0 = hw.instance "testSingleWithExt_p0_s0" @testSingleWithExt_p0_s0(in0: %in0: i32, in1: %in1: i32, clk: %clk: i1, rst: %rst: i1) -> (out0: i32)
    %testSingleWithExt_p0_s1.out0 = hw.instance "testSingleWithExt_p0_s1" @testSingleWithExt_p0_s1(in0: %testSingleWithExt_p0_s0.out0: i32, extIn0: %extIn0: i32, clk: %clk: i1, rst: %rst: i1) -> (out0: i32)
    hw.output %testSingleWithExt_p0_s1.out0, %extIn0 : i32, i32
  }
  hw.module @testSingleWithExt_p0_s0(%in0: i32, %in1: i32, %clk: i1, %rst: i1) -> (out0: i32) {
    %true = hw.constant true
    %0 = comb.sub %in0, %in0 : i32
    %s0_reg0 = seq.compreg %0, %clk : i32
    hw.output %s0_reg0 : i32
  }
  hw.module @testSingleWithExt_p0_s1(%in0: i32, %extIn0: i32, %clk: i1, %rst: i1) -> (out0: i32) {
    %true = hw.constant true
    %0 = comb.add %in0, %extIn0 : i32
    %s1_reg0 = seq.compreg %0, %clk : i32
    hw.output %s1_reg0 : i32
  }
  hw.module @testSingleWithExt(%arg0: i32, %ext1: i32, %clk: i1, %rst: i1) -> (out0: i32, out1: i32) {
    %testSingleWithExt_p0.out0, %testSingleWithExt_p0.out1 = hw.instance "testSingleWithExt_p0" @testSingleWithExt_p0(in0: %arg0: i32, in1: %arg0: i32, extIn0: %ext1: i32, clk: %clk: i1, rst: %rst: i1) -> (out0: i32, out1: i32)
    hw.output %testSingleWithExt_p0.out0, %testSingleWithExt_p0.out1 : i32, i32
  }

Note: The pipeline op signature is getting unruly, given that all inputs are bundled into the single ^bb0 definition. In a future commit, i plan to specialize the printer/parser for the pipeline op to mimick something like the scf ops, such that we have a bit more sane format.

  %out:2 = pipeline.scheduled(%arg0) ext(%arg1 : i32) clock %clk reset %rst : (i32, i32) -> (i32, i32) {
    ^bb0(%a0 : i32, %ext0: i32):

// vs

%out:2 = pipeline.scheduled(%a0 : i32 = %arg0) ext(%ext0 = %arg1 : i32) clock %clk reset %rst -> (i32, i32) {

@mortbopet mortbopet requested a review from teqdruid June 9, 2023 12:16
@mortbopet mortbopet changed the base branch from dev/mpetersen/refactor_pipeline to main June 12, 2023 09:13
@mortbopet mortbopet force-pushed the dev/mpetersen/pipeline_pass_input branch from f9d6663 to b1d1679 Compare June 12, 2023 09:20
Copy link
Contributor

@teqdruid teqdruid left a comment

Choose a reason for hiding this comment

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

thanks!


// The entry block defines a lot of SSA values...
// drop everything but the 'input's to the stage
return stage->getArguments().take_front(getInputs().size());
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 uncomfortable with making the assumption that the inputs are the first group of block args, but I don't think there's any alternative. Matt was commenting on something similar (having to rely on port numbers rather than named symbols). You might think on a solution for both and if the problems relate.

Just something I want to put in your brain.

Copy link
Contributor

Choose a reason for hiding this comment

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

For this, is there anything that ODS generates which could be used to get the offset? (Which would be zero with the current ODS def.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to

  return stage->getArguments().slice(getInputs().getBeginOperandIndex(), getInputs().size());

inputs = mod.getArguments().take_front(nStageInputArgs);
extInputs = mod.getArguments().slice(
nStageInputArgs, parent.getStageExtInputs(block).size());
clock = mod.getArgument(mod.getNumArguments() - 2);
Copy link
Contributor

Choose a reason for hiding this comment

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

Magic constants. Eww. Can you define some (perhaps public) offset constants for these? Or an attribute? We should really come up with an efficient way to access port indexes by name.

lib/Conversion/PipelineToHW/PipelineToHW.cpp Outdated Show resolved Hide resolved
lib/Conversion/PipelineToHW/PipelineToHW.cpp Outdated Show resolved Hide resolved
lib/Conversion/PipelineToHW/PipelineToHW.cpp Outdated Show resolved Hide resolved
@mortbopet mortbopet force-pushed the dev/mpetersen/pipeline_pass_input branch from 7cc3cb6 to 16712d3 Compare June 19, 2023 08:50
`ext` inputs are inputs which are accessible in any pipeline stage, and which will never be registered during register materialization. If you imagine a pipeline as signals going from left to right with registers in between, `ext` inputs are inputs that hook in from the top or bottom, into any pipeline stage.

In hardware (outlined) lowering, the external inputs are only provided to stages which actually reference them.

**Note**: The pipeline op signature is getting unruly, given that all inputs are bundled into the single `^bb0` definition. In a future commit, i plan to specialize the printer/parser for the pipeline op to mimick something like the `scf` ops, such that we have a bit more sane format.

```mlir
  %out:2 = pipeline.scheduled(%arg0) ext(%arg1 : i32) clock %clk reset %rst : (i32, i32) -> (i32, i32) {
    ^bb0(%a0 : i32, %ext0: i32):

// vs

%out:2 = pipeline.scheduled(%a0 : i32 = %arg0) ext(%ext0 = %arg1 : i32) clock %clk reset %rst -> (i32, i32) {
```
@mortbopet mortbopet force-pushed the dev/mpetersen/pipeline_pass_input branch from 41dc5e6 to 9bd8741 Compare June 20, 2023 07:52
@mortbopet mortbopet merged commit 2c67328 into main Jun 20, 2023
@darthscsi darthscsi deleted the dev/mpetersen/pipeline_pass_input branch June 4, 2024 14:50
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.

2 participants