Xilinx / RapidWright

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

Merging designs with naming collision encrypted cells #872

Closed nqdtan closed 10 months ago

nqdtan commented 10 months ago

Please find the relevant checkpoint and EDIF files attached. My code is as follows

  public static void main(String[] args) throws FileNotFoundException {
      Design design0 = Design.readCheckpoint("checkpoints/socket0/socket0.dcp", "checkpoints/socket0/socket0.edf");
      EDIFNetlist netlist0 = design0.getNetlist();
      Design design1 = Design.readCheckpoint("checkpoints/socket1/socket1.dcp", "checkpoints/socket1/socket1.edf");
      EDIFNetlist netlist1 = design1.getNetlist();

      Device dev = design0.getDevice();

      // Rename design to avoid name collision
      design0.setName("design0_" + design0.getName());
      design1.setName("design1_" + design1.getName());

      // Add prefix to all logical cells to avoid name collision
      netlist0.getWorkLibrary().uniqueifyCellsWithPrefix("design0_");
      netlist1.getWorkLibrary().uniqueifyCellsWithPrefix("design1_");

      Design newDesign = new Design("new_top_design", design0.getPartName());
      Module module0 = new Module(design0);
      ModuleInst modInst0 = newDesign.createModuleInst("socket_inst0", module0);
      modInst0.unplace(); // not worry about place&route for now

      Module module1 = new Module(design1);
      ModuleInst modInst1 = newDesign.createModuleInst("socket_inst1", module1);
      modInst1.unplace(); // not worry about place&route for now

      newDesign.getNetlist().addEncryptedCells(netlist0.getEncryptedCells());
      newDesign.getNetlist().addEncryptedCells(netlist1.getEncryptedCells());

      newDesign.writeCheckpoint("checkpoints/new_top_design.dcp");
      EDIFTools.writeEDIFFile("checkpoints/new_top_design.edf", newDesign.getNetlist(), newDesign.getPart().getName());
  }

Here, I attempt to combine the two designs socket0 and socket1 using ModuleInst. They have some common cells, and they are produced from the same flow separately. I have added some prefixes to avoid naming conflicts. When I loaded the checkpoint in Vivado using the generated new_top_design_load.tcl, I got the following error

Screenshot from 2023-11-06 21-53-13

which is not surprising because the encrypted cells (floating_point_*) also got renamed as well, so they did not match the cells defined in the existing encrypted *.edn files located in checkpoints/socket0/*.edn and checkpoints/socket1/*.edn.

On the other hand, some encrypted cells between the two designs share similar names, but have different interfaces, so I cannot simply unify these cells to the same name. For example, as shown in the following screenshots, checkpoints/socket0/floating_point_v7_1_15__parameterized1.edn refers to fcmp_32 op in design0, while checkpoints/socket1/floating_point_v7_1_15__parameterized1.edn refers to fadd_32 op in design1.

Screenshot from 2023-11-06 21-39-05

Screenshot from 2023-11-06 21-40-19

Do you have any advice on how to solve this issue? Thanks!

merge_issue.zip

nqdtan commented 10 months ago

I have found a workaround to avoid the naming collision of encrypted cells, in particulars those involving Xilinx floating point IPs. Basically, I need to enable the option of generating synthesized checkpoints for these IPs in Vivado:

set_property generate_synth_checkpoint true [get_files cl_linear_fadd_32ns_32ns_32_3_primitive_dsp_1_ip.xci]

This will enforce Vivado to prepend the module name cl_linear_fadd_32ns_32ns_32_3_primitive_dsp_1_ip to the encrypted cell name. Therefore, we get something like this in the final design checkpoint

Screenshot from 2023-11-07 02-01-11

With this, I should be able to distinguish the encrypted cells from different designs.

clavin-xlnx commented 10 months ago

One other thing that might be useful in mitigating this issue is the Vivado Tcl command rename_ref:

rename_ref -help
rename_ref

Description: 
rename a cell ref

Syntax: 
rename_ref  [-ref <arg>] [-to <arg>] [-prefix_all <arg>] [-quiet] [-verbose]

Usage: 
  Name           Description
  --------------------------
  [-ref]         Cell ref to rename
  [-to]          New name
  [-prefix_all]  Rename all eligible hierarchical cell refs in the current 
                 design.  Construct the new name using the given prefix plus 
                 the original name
  [-quiet]       Ignore command errors
  [-verbose]     Suspend message limits during command execution

Categories: 
Netlist

Description:

  Rename the reference name of a single non-primitive cell, or apply a
  reference prefix to all non-primitive cells in the current synthesized or
  implemented design.

  This command provides a mechanism to change the non-primitive reference
  names in the current design so that they do not collide with the reference
  names in another design. This lets two modules or designs be synthesized or
  simulated together, while avoiding any name collisions between the two
  designs.

  This command returns nothing when renaming the reference a single cell, and
  returns the number of cells renamed when used with -prefix_all. If the
  command fails, an error is returned.
nqdtan commented 10 months ago

Awesome!