Xilinx / RapidWright

Build Customized FPGA Implementations for Vivado
http://www.rapidwright.io
Other
286 stars 109 forks source link

Encrypted cell placement #838

Closed nqdtan closed 11 months ago

nqdtan commented 11 months ago

I would like to know if it is possible to relocate a design that contains some encrypted cells (e.g., floating point IP).

For example, I have the following minimal code derived from my project

    Design design = Design.readCheckpoint("fadd_routed.dcp", "fadd_routed.edf");
    EDIFNetlist netlist = design.getNetlist();

    Device dev = design.getDevice();
    EDIFCell top = netlist.getTopCell();

    HashSet<Cell> oldCells = new HashSet<>(design.getCells());
    for (Cell c : oldCells) {
      design.removeCell(c);
      Cell newCell = new Cell(c.getName(), c.getSiteInst(), c.getBEL());
      design.addCell(newCell);
    }
    design.writeCheckpoint("test.dcp");

It simply clones and replaces all existing placed cells. The cells are all DSPFP32 primitives, and they corresponds to the logical cells defined in the encrypted floating_point_v7 IP. When I attempt to load the generated DCP in Vivado with the following script

read_edif floating_point_v7_1_15.edn
read_edif floating_point_v7_1_15_viv.edn
read_checkpoint test.dcp
set_property top fadd [current_fileset]
link_design -part xcvc1902-vsvd1760-2MP-e-S

I got this error in Vivado

link_design failed ERROR: [Common 17-49] Internal Data Exception: HDPLPlaceCatalogProto LibCellType bad id 0 in get!

However, if newCell is created by

Cell newCell = c.getReferenceCopy();

then there is no issue in loading the checkpoint in Vivado. But now all the cells are unplaced.

Is it possible to modify this code to generate a DCP that works in Vivado (i.e., retain/update the placement information for the newly created cells)?

Thanks.

fadd_test.zip

clavin-xlnx commented 11 months ago

Absolutely yes, this is possible. The simplest way--if the entire design needs to be relocated--is to use the API in RelocationTools. This will move all the logic and routing by some specified offset amount in tile row/column units.

Suppose you wanted to move your design up (North) such that the DSP cell (fadd_ip_u/inst/i_synth/ADDSUB_OP.ADDSUB/PRIM.OP/i_prim) is moved from DSP_X0Y0 to DSP_X0Y5. We would need to calculate the tile offset for this move, which is to offset the row by 10:

Site Name Tile Name Tile Y Coordinate RapidWright API
DSP_X0Y0 DSP_ROCF_B_TILE_X29Y4 4 Device.getSite("DSP_X0Y0").getTile().getTileYCoordinate()
DSP_X0Y5 DSP_ROCF_B_TILE_X29Y14 14 Device.getSite("DSP_X0Y5").getTile().getTileYCoordinate()

We can modify your example code to perform this relocation as follows:

    Design design = Design.readCheckpoint("fadd_routed.dcp");

    if (!RelocationTools.relocate(design, design.getSiteInsts(), 0, 10)) {
        throw new RuntimeException("ERROR: Failed to relocate design");
    }

    design.writeCheckpoint("test.dcp");

Before: image

After: image

Notice that after the move, the routing is also relocated despite it looking somewhat different in the GUI.

If the offset is not correct or if the landing spot for the logic is not compatible with the offset provided, the relocation will fail and return false.

There are other ways to relocate logic as well, even if the design has encrypted cells. One of the keys of enabling this is that the process begin with a design that is at least placed. An unplaced design with encrypted cells will not be able to be placed and/or relocated.

nqdtan commented 11 months ago

Thanks for the detailed example, Chris. I'll definitely check out RelocationTools.relocate method to see if I can utilize it to streamline my work flow.

A quick question, then: does RapidWright also support copying (replicating) existing design with encrypted cells to a new design (which is actually what I was trying to do)?

clavin-xlnx commented 11 months ago

A quick question, then: does RapidWright also support copying (replicating) existing design with encrypted cells to a new design (which is actually what I was trying to do)?

Sure, to replicate, you'll want to use the Module and ModuleInst objects that allow you to turn a design into a template or "stamp" of a design. This essentially gives you an extra level of hierarchy in the physical netlist.

If we want to replicate your DSP IP twice (one to live each at DSP_X0Y0 and DSP_X0Y5), we can do so like this (you'll need #842 before this can work):

import java.util.Arrays;

import com.xilinx.rapidwright.design.Design;
import com.xilinx.rapidwright.design.Module;
import com.xilinx.rapidwright.design.ModuleInst;
import com.xilinx.rapidwright.device.Device;

public class EncryptedCellPlacement {

    public static void main(String[] args) {
        Design design = Design.readCheckpoint("fadd_test/fadd_routed.dcp");
        Module module = new Module(design);
        Device device = design.getDevice();
        Design newDesign = new Design("new_top_design", design.getPartName());

        for (String newLoc : Arrays.asList("DSP_X0Y0", "DSP_X0Y5")) {
            ModuleInst modInst = newDesign.createModuleInst("inst_" + newLoc, module);
            if (!modInst.place(device.getSite(newLoc))) {
                throw new RuntimeException("ERROR: Unable to place module instance " 
                        + modInst.getName() + " at anchor location " + newLoc);
            }

        }

        // Moving encrypted cell references is not yet automatic, we have to manage it ourselves...
        newDesign.getNetlist().addEncryptedCells(design.getNetlist().getEncryptedCells());

        newDesign.writeCheckpoint("new_top_design.dcp");
    }
}

In Vivado: image

The inter-site routing is not preserved because there are only two routable nets present (GND and VCC), however, there are fixes in the works to support keeping these, but generally, re-routing GND and VCC in a multi-instance context is not a big deal. The GND and VCC preservation fixes might likely be in the next release (2023.1.4).

nqdtan commented 11 months ago

This is terrific, thanks!