chipsalliance / chisel

Chisel: A Modern Hardware Design Language
https://www.chisel-lang.org/
Apache License 2.0
3.9k stars 585 forks source link

(Optionally?) Add FIRRTL Pretty Printing #3219

Open seldridge opened 1 year ago

seldridge commented 1 year ago

For any non-trivial design, the sizes of bundles can get very, very large. This is particularly apparent for modules which use libraries which auto-generate a ton of ports and put them all in the same bundle (i.e., diplomacy). This can create modules like:

module Foo:
  input clock: Clock
  input reset: UInt<1>
  input auto: { a: { ... }, b: { ... }, c : { d: { e: ... } } }

FIRRTL technically supports line breaks in types. The above could be made much more readable in the FIRRTL output as:

module Foo:
  input clock: Clock
  input reset: UInt<1>
  input auto: { 
    a: { ... }, 
    b: { ... }, 
    c : { 
      d: { 
        e: ... 
      } 
    }
  }

Experiment with an option to turn this on and see the effect on the output and the serialization time. (FIRRTL does not have type annotations which means these would only show up on ports, wires, and registers.) See about making this the default. If we do this, enshrine it in the FIRRTL spec as legal.

seldridge commented 1 year ago

@dtzSiFive landed support for this on the CIRCT side in https://github.com/llvm/circt/commit/d4ab551d910800632cdde403b5834c326d8c76fd. If you use the FIRRTL exporter that it provides, you now get the behavior above. This should be available in firtool 1.42 (next week).

E.g., the old FPU.fir regression test now looks like (firtool FPU.fir -parse-only | circt-translate -export-firrtl):

circuit FPU :
  module FPU :
    input clock : Clock
    input reset : UInt<1>
    output io : { flip inst : UInt<32>,
                  flip fromint_data : UInt<64>,
                  flip fcsr_rm : UInt<3>,
                  fcsr_flags : { valid : UInt<1>, bits : UInt<5> },
                  store_data : UInt<64>,
                  toint_data : UInt<64>,
                  flip dmem_resp_val : UInt<1>,
                  flip dmem_resp_type : UInt<3>,
                  flip dmem_resp_tag : UInt<5>,
                  flip dmem_resp_data : UInt<64>,
                  flip valid : UInt<1>,
                  fcsr_rdy : UInt<1>,
                  nack_mem : UInt<1>,
                  illegal_rm : UInt<1>,
                  flip killx : UInt<1>,
                  flip killm : UInt<1>,
                  dec
                    : { cmd : UInt<5>,
                        ldst : UInt<1>,
                        wen : UInt<1>,
                        ren1 : UInt<1>,
                        ren2 : UInt<1>,
                        ren3 : UInt<1>,
                        swap12 : UInt<1>,
                        swap23 : UInt<1>,
                        single : UInt<1>,
                        fromint : UInt<1>,
                        toint : UInt<1>,
                        fastpipe : UInt<1>,
                        fma : UInt<1>,
                        div : UInt<1>,
                        sqrt : UInt<1>,
                        wflags : UInt<1> },
                  sboard_set : UInt<1>,
                  sboard_clr : UInt<1>,
                  sboard_clra : UInt<5>,
                  flip cp_req
                    : { flip ready : UInt<1>,
                        valid : UInt<1>,
                        bits
                          : { cmd : UInt<5>,
                              ldst : UInt<1>,
                              wen : UInt<1>,
                              ren1 : UInt<1>,
                              ren2 : UInt<1>,
                              ren3 : UInt<1>,
                              swap12 : UInt<1>,
                              swap23 : UInt<1>,
                              single : UInt<1>,
                              fromint : UInt<1>,
                              toint : UInt<1>,
                              fastpipe : UInt<1>,
                              fma : UInt<1>,
                              div : UInt<1>,
                              sqrt : UInt<1>,
                              wflags : UInt<1>,
                              rm : UInt<3>,
                              typ : UInt<2>,
                              in1 : UInt<65>,
                              in2 : UInt<65>,
                              in3 : UInt<65> } },
                  cp_resp
                    : { flip ready : UInt<1>,
                        valid : UInt<1>,
                        bits : { data : UInt<65>, exc : UInt<5> } } }