Xilinx / RapidWright

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

No possible Unisim of VCC and GND for 7-series FPGAs #958

Closed dg-deus closed 6 months ago

dg-deus commented 6 months ago

I want to create a simple logical netlist, which contains a flip-flop like FDCE and VCC/GND sources based on RapidWright in python. Then, I want to place this simple circuit in a single site. More specifically, I want the VCC in the logical netlist to be mapped to CEUSEDVCC and GND to SRUSEDGND BELs.

However, I cannot generate such logical netlist, because it seems like there is no Unisim of VCC and GND supported for 7-series FPGAs.

How can I generate such logical netlist and do P&R using RapidWright APIs in python?

clavin-xlnx commented 6 months ago

We currently don't have a clock router that targets Series 7 devices, but you can do everything else in RapidWright. Here is an example in Python3 code that will generate a placed and routed DCP (minus route the clock net--can be routed in Vivado) that is similar to the circuit you described: image

import rapidwright

from com.xilinx.rapidwright.device import Device
from com.xilinx.rapidwright.design import Design
from com.xilinx.rapidwright.design import Unisim
from com.xilinx.rapidwright.design import NetType
from com.xilinx.rapidwright.design import PinType
from com.xilinx.rapidwright.edif import EDIFHierNet
from com.xilinx.rapidwright.edif import EDIFTools
from com.xilinx.rapidwright.router import Router

designName = 'FDCE_Netlist'
d = Design(designName, Device.PYNQ_Z1)

ff = d.createAndPlaceCell("ff", Unisim.FDCE, "SLICE_X100Y100/AFF")
clkInput = d.createAndPlaceIOB("clk", PinType.IN, "H16", "LVCMOS33")
button0 = d.createAndPlaceIOB("button0", PinType.IN, "D19", "LVCMOS33")
led0 = d.createAndPlaceIOB("led0", PinType.OUT, "R14", "LVCMOS33")
bufgctrl = d.createAndPlaceCell("bufgce", Unisim.BUFGCTRL, "BUFGCTRL_X0Y16/BUFGCTRL")

clkIn = d.createNet("clkIn")
clkIn.connect(clkInput, "O")
clkIn.connect(bufgctrl, "I0")

clk = d.createNet("clk_IBUF")
clk.connect(ff, "C")
clk.connect(bufgctrl, "O")

buttonIn = d.createNet("buttonIn")
buttonIn.connect(ff, "D")
buttonIn.connect(button0, "O")

ledOut = d.createNet("ledOut")
ledOut.connect(ff, "Q")
ledOut.connect(led0, "I")

topInst = d.getNetlist().getTopHierCellInst()
top = d.getTopEDIFCell()
n = d.getNetlist()

vcc = d.getVccNet()
vcc.setLogicalHierNet(EDIFHierNet(topInst, EDIFTools.getStaticNet(NetType.VCC, top, n)))
vcc.connect(ff, "CE")
for pin in [ "CE0", "IGNORE1", "I1", "S0" ]:
    vcc.connect(bufgctrl, pin)

gnd = d.getGndNet()
gnd.setLogicalHierNet(EDIFHierNet(topInst, EDIFTools.getStaticNet(NetType.GND, top, n)))
gnd.connect(ff, "CLR")
for pin in [ "CE1", "IGNORE0", "S1" ]:
    sitePin = gnd.connect(bufgctrl, pin)
    # Use the inverter to route to VCC instead
    gnd.removePin(sitePin)
    vcc.addPin(sitePin)

# Route site internal nets
d.routeSites()

# Route nets between sites
Router(d).routeDesign()

# Save our work in a Checkpoint
d.writeCheckpoint(designName + ".dcp")

You can easily route the clock net in Vivado after opening it by running the Tcl command

route_design -nets [get_nets { clk_IBUF }]
dg-deus commented 6 months ago

Thank you for the code!

However, what I was wondering is a way to use VCC within a site manually like the following code.

localvcc = d.createAndPlaceCell("localvcc", Unisim.VCC, "SLICE_X100Y100/CEUSEDVCC")

java.lang.NullPointerException occurs when I run this code for 7-series FPGAs.

clavin-xlnx commented 6 months ago

In the example above, it is using the VCC inside the SLICE source (CEUSEDVCC): image There is just no cell to place on the BEL to activate it. It is inferred by the site routing.