verilog-to-routing / vtr-verilog-to-routing

Verilog to Routing -- Open Source CAD Flow for FPGA Research
https://verilogtorouting.org
Other
1.01k stars 391 forks source link

Best way to express "routing BELs" in vpr #284

Open mithro opened 6 years ago

mithro commented 6 years ago

In many architectures there are things called "routing BELs" / "routing muxes" (RMUX) which are elements found inside a logic cell which route signals around them. These RMUXs are important as they need to be configured correctly to make the logic function correctly.

I'm after some advice about the best way to represent these in vpr FPGA architecture definition.

So far the two possibilities I've come up with are as follows;


Option 1 - pb_type with <mux> in interconnect

See the following pb_type definition below;

<pb_type name="AOUTMUX" num_pb="1">
 <input name="A5Q" num_pins="1"/>
 <input name="XOR" num_pins="1"/>
 <input name="O6" num_pins="1"/>
 <input name="O5" num_pins="1"/>
 <input name="F7" num_pins="1"/>
 <input name="CY" num_pins="1"/>
 <output name="OUT" num_pins="1"/>
 <interconnect>
   <mux input="AOUTMUX.A5Q AOUTMUX.XOR AOUTMUX.O6 AOUTMUX.O5 AOUTMUX.F7 AOUTMUX.CY" name="AOUTMUX_IN" output="AOUTMUX.OUT"/>
 </interconnect>
</pb_type>

This produces a .place file which looks like this;

<block name="open" instance="AOUTMUX[0]" mode="AOUTMUX">
    <inputs>
        <port name="A5Q">open </port>
        <port name="XOR">open </port>
        <port name="O6">open </port>
        <port name="O5">ALUT[0].O5[0]->AOUTMUX_IN_O5  </port>
        <port name="F7">open </port>
        <port name="CY">open </port>
    </inputs>
    <outputs>
        <port name="OUT">AOUTMUX[0].O5[0]->AOUTMUX_IN  </port>
    </outputs>
    <clocks>
    </clocks>
</block>

With this output the only way to determine which configuration the AOUTMUX is in is via looking at which of the <inputs> has had a signal assign to it.


Option 2 - pb_type with <mode>s and single <direct> in the interconnect

This is another option that seems to work. Instead of using the <mux> construct, you use the <mode> construct with a single <direct> connection in each mode. See below;

<pb_type name="AOUTMUX" num_pb="1">
 <input name="A5Q" num_pins="1"/>
 <input name="XOR" num_pins="1"/>
 <input name="O6" num_pins="1"/>
 <input name="O5" num_pins="1"/>
 <input name="F7" num_pins="1"/>
 <input name="CY" num_pins="1"/>
 <output name="OUT" num_pins="1"/>
 <mode name="A5Q">
  <interconnect>
   <direct input="AOUTMUX.A5Q" name="AOUTMUX.A5Q" output="AOUTMUX.OUT"/>
  </interconnect>
 </mode>
 <mode name="XOR">
  <interconnect>
   <direct input="AOUTMUX.XOR" name="AOUTMUX.XOR" output="AOUTMUX.OUT"/>
  </interconnect>
 </mode>
 <mode name="O6">
  <interconnect>
   <direct input="AOUTMUX.O6" name="AOUTMUX.O6" output="AOUTMUX.OUT"/>
  </interconnect>
 </mode>
 <mode name="O5">
  <interconnect>
   <direct input="AOUTMUX.O5" name="AOUTMUX.O5" output="AOUTMUX.OUT"/>
  </interconnect>
 </mode>
 <mode name="F7">
  <interconnect>
   <direct input="AOUTMUX.F7" name="AOUTMUX.F7" output="AOUTMUX.OUT"/>
  </interconnect>
 </mode>
 <mode name="CY">
  <interconnect>
   <direct input="AOUTMUX.CY" name="AOUTMUX.CY" output="AOUTMUX.OUT"/>
  </interconnect>
 </mode>
</pb_type>

This produces a .place file which looks like this;

<block name="open" instance="AOUTMUX[0]" mode="O5">
    <inputs>
        <port name="A5Q">open </port>
        <port name="XOR">open </port>
        <port name="O6">open </port>
        <port name="O5">ALUT[0].O5[0]->AOUTMUX_IN_O5  </port>
        <port name="F7">open </port>
        <port name="CY">open </port>
    </inputs>
    <outputs>
        <port name="OUT">AOUTMUX[0].O5[0]->AOUTMUX_IN  </port>
    </outputs>
    <clocks>
    </clocks>
</block>

From the mode="O5" setting, this output it is clear that the mux is selecting the O5 signal -- which seems rather nice.


Affects?

How do these two options end up being represented inside vpr? Do they make any difference in how vpr will perform?

kmurray commented 6 years ago

First, a quick correction; I think by .place file you actually mean the .net file produced by packing.

I think (1) is much clearer than (2). It is also much more explicit about the structure you are trying to model.

However, do you need to wrap the <mux> in it's own ? That seems a bit of overkill (unless I'm missing something). You could just implement the directly with something like:

<mux name="AOUTMUX" input="A5Q XOR O6 O5 F7 CY" output="AOUTMUX.OUT"/>

With this output the only way to determine which configuration the AOUTMUX is in is via looking at which of the has had a signal assign to it.

This is true, internally VPR represents all the <mux>/<direct>/<complete>s as edges in a routing graph (within the cluster). Once a cluster is routed it knows, for example, which 'leg' of the mux (edge in the routing graph) is being used by a particular connection. That is all the information required to determine how the mux configuration bits should be set.

The .net file format describes this somewhat oddly, but the same information can be recovered.

How do these two options end up being represented inside vpr? Do they make any difference in how vpr will perform?

(1) will encode the 'mux' into the (intra-cluster) routing graph (2) will encodes the 'mux' as a group of modes (not in the routing graph)

The cluster handles mode assignment first, places the netlist primitives based on the mode selection and then routes everything together.

As a result I would expect (1) to produce the best result (since it gives the router the most flexibility). I'm actually not sure whether (2) would even work; but if it did it would significantly restrict the router's flexibility, likely hurting both run-time and QoR.

So I'd recommend (1). The usual way we've handled this in the past is as I described above, where the <mux> isn't wrapped in it's own <pb_type>.

cmanovit commented 2 years ago

Since these routing muxes are intra-block, could we also run into #325 (e.g., these intra-block routing, though not visible to packer, may be required in order to fulfill its assumption that it can always 'route outside')?