Search code examples
scalachiselregister-transfer-level

Use FIRRTL Annotations to connect multi-bit wires and pins


I am writing down some firrtl transforms and I am using annotations to connect pins and wires, like :

 val named = ComponentName(inputWire.name, ModuleName(mod.name, CircuitName(top)))
 val anno = Traversable(SinkAnnotation(named, pinName))

The inputWire is :

 val inputWire = DefWire(NoInfo,localNS.newTemp, con.expr.tpe)

And the pinName is a string :

val pinName = namespace.newName(faultPinPrefix)

where the type of inputWire is UIntType(IntWidth(2)) or it could be more than 2 on some other cases.

After this transform, I run the firrtl.passes.wiring.WiringTransform to issue the connections The problem I'm facing right now is that the verilog output is like below :

input       faultPin_0
//...
//Some code
//..
 assign _GEN_1 = {{1'd0}, faultPin_0};

This is not the behavior I expect. It is creating an input port of 1 bit only, and it is concatenating it, it create the 2 bit signal. Maybe the problem is that I am not specifying the type of the port, I am letting the compiler decide for it, and it is automatically creating a 1 bit port. Is there any way to make this connection using annotations, or I should focus on finding another approach which is more feasible.


Solution

  • The WiringTransform will wire multi-bit components and does include a test of this.

    However, the type of the pin is a function of the source and not a function of the sink. Can you verify that your source is also a multi-bit signal?

    For the test referenced above the following FIRRTL:

    circuit Top :
      module Top :
        input clk: Clock
        inst x of X
        x.clk <= clk
        reg r: UInt<5>, clk
      module X :
        input clk: Clock
        wire s: UInt<5>
    

    And the following annotations:

    • SourceAnnotation(ComponentName("r", ModuleName("Top", CircuitName("Top"))), "pin")
    • SinkAnnotation(ComponentName("s", ModuleName("X", CircuitName("Top"))), "pin")

    Produces the following circuit when run through the WiringTransform:

    circuit Top :
      module Top :
        input clk: Clock
        wire r_0 : UInt<5>
        inst x of X
        x.clk <= clk
        reg r: UInt<5>, clk
        x.pin <= r_0
        r_0 <= r
      module X :
        input clk: Clock
        input pin: UInt<5>
        wire s: UInt<5>
        s <= pin
    

    This seems to be right. However, if I make the source a 1-bit signal (reg r: UInt<1>, clk), then the pin will also be 1-bit (input pin : UInt<1>).