Xilinx / RapidWright

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

Cannot import a placed and routed design that has a Unisim.INV cell into Vivado #40

Closed hcook95 closed 4 years ago

hcook95 commented 5 years ago

I am creating a design where I need to place inverters at very specific LUTs. I was using Lesson1.java as a template to do so. It works when I use the Unisim.AND2 as the cellType parameter for the createAndPlaceCell method , but when I change it to Unisim.INV, I get the following error when I import the generated checkpoint into Vivado:

[Constraints 18-4518] Instance not_gate had Lib Cell Type INV which is different than LUT1.

where not_gate is the name of my place inverter cell. Upon further investigation, I found that for the AND2 cell, the cell type for the cell's EDIFCellInst is a LUT2, while the cell type for the INV's EDIFCellInst is INV. I also noticed that the INIT property for the AND2's EDIFCellInst is a truth table for a 2 input AND gate, while the INV's EDIFCellInst lacks the INIT property altogether.

So my question is, what am I doing wrong, and what is the easiest way to place an inverter at a specific LUT?

My edit of Lesson1.java can be found here: inv_example.zip

clavin-xlnx commented 5 years ago

Your approach makes sense and it is clear that this behavior is not as you intended. There are a set of Unisims that get remapped—such as AND2 to a LUT2—automatically. I believe there may be places in the fabric that can accept a placed INV, but it appears a LUT site is not one of them and is not automatically remapped. Here is what I would suggest:

I will look into seeing about an automatic remapping of the INV to a LUT1 that is configured as an inverter when I get some time next week.

In the mean time, I would recommend directly instantiating a LUT1 and modifying the LUT equation to match inverter behavior. There is a class especially created to help set LUT equations called LUTTools:

https://github.com/Xilinx/RapidWright/blob/master/com/xilinx/rapidwright/design/tools/LUTTools.java

See the LUTTools.configureLUT(Cell cell, String equation ) method. I believe the inverter string should be ”O=~A1” (I will be away from a computer until next week).

Hope that helps.

hcook95 commented 5 years ago

Using the LUTTools.configureLUT(Cell cell, String equation ) method worked great! I did run into a small bug though. When instantiating the cell with a LUT1, there seemed to be a discrepancy between the input port of the LUT1 EDIFCell, and the logical pin mapping of the Cell. This would create problems when I tried to connect a net to the input of the NOT gate (line 28 in the attached). I would get a java.lang.NullPointerException when I used either the EDIFCell's "I0" or the Cell's "I" as the name of the logical pin (although they would occur in different places within the connect(Cell c, String logicalPinName) method). This was fixed by adding the following lines (lines 20 and 21 in the attached code):

not.removePinMapping("A6");
not.addPinMapping("A6", "I0");

The above code removes the discrepancy and adds a physical pin mapping that agrees with the port of the EDIFCell. After adding this into my code my code worked as expected and I was able to generate a bitstream that did what I wanted.

My code can be found here: inv_example.zip

clavin-xlnx commented 4 years ago

I believe this issue was resolved, if not please don't hesitate to re-open. Running the inv_example.zip code without the two lines of work-around code works correctly and generates a bitstream in Vivado.