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

[Not-for-commit] Demonstrate Yosys integration #7663

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

uenoku
Copy link
Member

@uenoku uenoku commented Oct 4, 2024

This PR demonstrates Yosys integration (my side-project for few months 😄 )which interacts with Yosys's IR (RTLIL). Yosys is de-facto standard as an opensource RTL synthesis and verification tool. The purpose of the yosys integration is to serve as a baseline for circt-based synthesis flow. It's super experimental and this PR needs to be separated into 5~7 PRs (and cleaned up quite a bit) for review. This integration work is inspired by HEIR's Yosys optimizer pass but in this PR we directly translate CIRCT IR to RTLIL instead of using SystemVerilog. This integration makes it possible to import designs from RTLIL so technically we can use the circuits generated by framework based on Yosys such as amaranth-lang/amaranth.

Build

Yosys integration is disabled by default. To enable Yosys integration, you need to build CIRCT with -DCIRCT_YOSYS_INTEGRATION_ENABLED=ON. This will download Yosys release and generate a shared lib (as you can see the CMakeFile it was fairly to tricky to do so maybe it's better to requires users to install specific version of Yosys for simplicity.

Tranlation between RTLIL

circt-translate provides subcommand for translation between CIRCT IR and RTLIL.

  • CIRCT IR -> RTLIL
circt-tranlsate --export-rtlil

Currently only subest of core dialects are translated during translation to RTLIL.

  • RTLIL -> CIRCT IR
circt-tranlsate --import-rtlil

Run Yosys passes on CIRCT IR

To run Yosys passes on CIRCT there are two passes yosys-optimizer and yosys-optimizer-parallel.

# Run synth (canonicalizer is currently required to get "clean" core dialect operations)
circt-opt  -pass-pipeline='builtin.module(yosys-optimizer{passes=synth},canonicalize)'

# Pipe Yosys log to the stderr via `redirect-log=true`.
circt-opt  -pass-pipeline='builtin.module(yosys-optimizer{passes=synth redirect-log=true})'

# Run synth_xilinx (symbol-dce is recommended to remove unused external modules)
circt-opt  -pass-pipeline='builtin.module(yosys-optimizer{passes=synth_xilinx},canonicalize,symbol-dce)'

# Run multiple yosys pass (comma separated).
circt-opt  -pass-pipeline='builtin.module(yosys-optimizer{passes=write_rtlil,write_verilog,synth},canonicalize)'

# Emit Verilog using yosys backend. It's recommended to run `opt` for the fair comparison
circt-opt  -pass-pipeline='builtin.module(yosys-optimizer{passes=opt,write_verilog})'

CIRCT as a parallel Yosys driver

Yosys has a globally context which is a not thread-safe so we cannot parallelly run yosys-optimizer on each HW module. As a workaround CIRCT provides a yosys-optimizer-parallel pass that parallelly invokes yosys in child processes. yosys-optimizer-parallel cannot be used for transformation that requires module hierarchly (e.g. inlining/flattening etc)

Testing

Testing Yosys integration is tricky since RTLIL textual format could differ between Yosys versions. Currently we test the correctness of RTLIL translation with a few round-trip tests and LEC on pre-and-post synthesis.

License

Yosys has ISC License so it should be fine to use it through shared lib.

Example

$  cat bar.mlir
hw.module @counter(in %clk: i1, out o: i4) {
  %seq_clk = seq.to_clock %clk

  %reg = seq.compreg %added, %seq_clk : i4

  %one = hw.constant 1 : i4
  %added = comb.add %reg, %one : i4

  hw.output %reg : i4
}

$  circt-opt --pass-pipeline='builtin.module(yosys-optimizer{passes=synth})' bar.mlir | firtool --format=mlir

// Generated by CIRCT firtool-1.86.0-49-gd0520fe1c-dirty
module counter( // <stdin>:2:3
  input        clk,     // <stdin>:2:25
  output [3:0] o        // <stdin>:2:40
);

  reg _$auto$ff_cc3A2663Aslice$87;      // <stdin>:47:35
  reg _$auto$ff_cc3A2663Aslice$88;      // <stdin>:52:35
  reg _$auto$ff_cc3A2663Aslice$89;      // <stdin>:57:35
  reg _$auto$ff_cc3A2663Aslice$90;      // <stdin>:62:35
  always_ff @(posedge clk) begin        // <stdin>:62:35
    automatic logic _GEN = _$auto$ff_cc3A2663Aslice$88 & _$auto$ff_cc3A2663Aslice$87;   // <stdin>:22:11, :47:35, :52:35
    _$auto$ff_cc3A2663Aslice$87 <= ~_$auto$ff_cc3A2663Aslice$87;        // <stdin>:12:10, :47:35
    _$auto$ff_cc3A2663Aslice$88 <=
      _$auto$ff_cc3A2663Aslice$88 ^ _$auto$ff_cc3A2663Aslice$87;        // <stdin>:17:11, :47:35, :52:35
    _$auto$ff_cc3A2663Aslice$89 <=
      ~_GEN & _$auto$ff_cc3A2663Aslice$89 | _GEN & ~_$auto$ff_cc3A2663Aslice$89;        // <stdin>:22:11, :24:11, :27:11, :31:11, :32:11, :33:11, :57:35
    _$auto$ff_cc3A2663Aslice$90 <=
      _$auto$ff_cc3A2663Aslice$89 & _GEN ^ _$auto$ff_cc3A2663Aslice$90; // <stdin>:22:11, :39:11, :42:11, :57:35, :62:35
  end // always_ff @(posedge)
  assign o =
    {_$auto$ff_cc3A2663Aslice$90,
     _$auto$ff_cc3A2663Aslice$89,
     _$auto$ff_cc3A2663Aslice$88,
     _$auto$ff_cc3A2663Aslice$87};      // <stdin>:47:35, :52:35, :57:35, :62:35, :82:11, :86:5
endmodule

$ circt-opt --pass-pipeline='builtin.module(yosys-optimizer{passes=opt,write_verilog})' bar.mlir 
/* Generated by Yosys 0.40 (git sha1 a1bb0255d65, g++ 8.5.0 -fPIC -Os) */

module counter(clk, o);
  (* src = "bar.mlir:7:12" *)
  wire [3:0] _0_;
  (* src = "bar.mlir:1:23" *)
  input clk;
  wire clk;
  (* src = "bar.mlir:1:37" *)
  output [3:0] o;
  reg [3:0] o;
  assign _0_ = o + (* src = "bar.mlir:7:12" *) 4'h1;
  always @(posedge clk)
    o <= _0_;
endmodule

@uenoku uenoku requested a review from darthscsi as a code owner October 4, 2024 09:15
@uenoku uenoku marked this pull request as draft October 4, 2024 10:06
@uenoku uenoku force-pushed the dev/hidetou/yosys-integration branch from 356d3e5 to 5f460f7 Compare October 4, 2024 13:10
This adds Yosys integration
@uenoku uenoku force-pushed the dev/hidetou/yosys-integration branch from 5f460f7 to e3d38a2 Compare October 4, 2024 13:12
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.

1 participant