cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Observer
Observer
6,355 Views
Registered: ‎03-17-2008

Conditional instantiation of GTX

Hi. I have a design that is configurable using several VHDL generics at the top level. These generics affect what is instantiated in the design using generate blocks. In one case, I have the option of instantiating a GTX.

 

I have a TCL file [*] that sets the LOC constraint for the GTX transmit pins with no other constraints. Everything is fine when the GTX is instantiated.

 

I'm using Vivado 2016.4, and I have run into a problem when the GTX is not instantiated. The PACKAGE_PIN constraints fail because there is no GTX attached to the pins, and the PACKAGE_PIN I'm giving can only be used for GTXs.

 

So now the question . . . does anyone know of a good solution to handle PACKAGE_PIN constraints when a GTX is conditionally instantiated? I would prefer for the tools to forget that the pin even exists, but I cannot conditionally specify the pins in the top level entity, and I do not want the tools to pick an arbitrary place for them.

 

I have tried leaving the pins unassigned in the VHDL code, I have tried assigning 'Z' to them, I have tried instantiating OBUFDS for the pair, but so far my various attempts fail to compile in one way or another. Can I force the pins to be optimized out?

 

Any help would be appreciated.

 

(If it makes any difference, this is in a Kintex 7 device.)

 

[*] I'm using a TCL file rather than an XDC file because I have been trying to do conditional constraints to solve this too.

0 Kudos
8 Replies
Highlighted
Teacher
Teacher
6,343 Views
Registered: ‎03-31-2012

@aricblumer 

 

>> I do not want the tools to pick an arbitrary place for them.

 

luckily this doesn't apply to GTX as they have dedicated pins which can't be moved.

As to conditionally instantiating the block, you don't have to disable the generation. It's all hardwired on the chip anyway, you might as well instantiate the IP and tie the pins which go to fabric so that the hard-wired blocks won't be activated. This will allow you to generate any signals from fabric into the IP easily.

- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.
0 Kudos
Highlighted
Observer
Observer
6,310 Views
Registered: ‎03-17-2008

Thanks for replying muzaffer!

 

Yes, I suspect that if I tie GTX fabric ports high or low the GTX will be optimized out, but one of the goals is to avoid synthesizing the GTX and associated IP completely. So I had an idea that appears to work.

 

First is to explain the problem in detail. Suppose a top-level pair of ports tx_n and tx_p are connected to a GTX if the GTX is instantiated. I use PACKAGE_PIN constraints in a .xdc file to indicate the pins those ports should use. If the GTX is not instantiated, the tools tie tx_n and tx_p to ground. Since they are now not associated with a GTX, the PACKAGE_PIN constraints fail because the specified pins must be connected to a GTX. It fails during placement. If I don't do the PACKAGE_PIN constraints when there is no GTX, then the tools pick a pin location for me. That is not acceptable either.

 

So what if I can remove the pin altogether if the GTX is not instantiated? It turns out I can do so indirectly. This is how . . .

 

When Vivado ties unused output pins low, it instantiates OBUF cells. So we end up with tx_n_OBUF_inst and tx_p_OBUF_inst. (Names given by Vivado 2016.4; other versions may change those.) Now it is not possible to remove a top-level pin that is declared in RTL, but it is possible to remove those OBUF cells, and the pins are subsequently removed as a result. So I put something like the following in a .tcl file and then run that .tcl file in the impl_1.STEPS.PLACE DESIGN.TCL.PRE property [*]:

 

if {"[get_cells gtx_gen.u_gtx]" == {}} {
puts "********* Removing [get_cells tx_?_OBUF_inst]";
remove_cell [get_cells tx_?_OBUF_inst]
}

 

The tx_?_OBUF_inst will find both tx_n_OBUF_inst and tx_p_OBUF_inst. The gtx_gen.u_gtx comes from a structure like this in the VHDL:

 

gtx_gen: if ENABLE_GTX generate
    u_gtx: gtx_wrapper
        port map ( ... );
end generate; 

 

Removing cells seems kind of drastic, but I justify it like this: My RTL does not instantiate an OBUF nor does it assign any value to the pin. So I am removing something that the tools added that my RTL does not express.

 

[*] Go to Design Runs. Click on impl_1. Click on the Properties tab in the Implementation Run Properties pane. Open STEPS, PLACE DESIGN, and TCL. Put your script in the PRE property.

0 Kudos
Highlighted
Teacher
Teacher
6,302 Views
Registered: ‎03-31-2012

@aricblumer

in my post I was suggesting that you tie-off the fabric side of the GTX controller not the TXp/n etc pins

 

 

>> First is to explain the problem in detail. Suppose a top-level pair of ports tx_n and tx_p are connected to a GTX if the GTX is instantiated.

>> I use PACKAGE_PIN constraints in a .xdc file to indicate the pins those ports should use.

>> If the GTX is not instantiated, the tools tie tx_n and tx_p to ground.

 

This can never work. Only GTX pins are dedicated and they can't be driven by fabric as you have observed. If you want to no see the hard-wired GTX blocks at all, your only option is to remove the pin constraints as you have done. To instantiate the hard-wired GTX blocks, there is no real synthesis necessary as there is no fabric logic other than the tie-offs.

- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.
0 Kudos
Highlighted
Observer
Observer
6,295 Views
Registered: ‎03-17-2008

Thanks again for replying @muzaffer, but it looks as though you aren't following what I'm saying. I must be doing a lousy job at explaining it.

 

I understand fully that you are suggesting tying off the fabric side of the GTX controller, which is why I said, "Yes, I suspect that if I tie GTX fabric ports high or low the GTX will be optimized out, but one of the goals is to avoid synthesizing the GTX and associated IP completely." I am not proposing to tie off the tx_n or tx_p pins. It is the tools that do that, forcing me to work around it. (Yes, you can default the tools not to do that, but that affects all pins non-driven pins, not just the ones causing problems.)

 

I realize that the GTXs are already in the FPGA silicon and do not require *logic* synthesis, but the IP instantiation is still required to go through the synthesis step. It is later mapped to the on-die logic. Also, in my case, the GTX instantiations are actually buried within other IP (such as SMPTE SDI and Ethernet MAC wrappers), and those do require logic synthesis that I want to avoid in some circumstances.

 

What I outline above is working. The GTX (and/or the GTX wrapper) is conditionally instantiated in the RTL with a top-level boolean generic (which I control with a non-project mode TCL script) using the VHDL structure in my second post. When ENABLE_GTX is false, the GTX wrapper is not instantiated in the RTL elaboration phase and will therefore not be present in the synthesis step. In that case, the tools tie off the outputs to ground which causes the pin mapping error. I work around that by removing OBUFs that the tools instantiate. The pins then disappear from the design during placement, and no errors occur.

 

0 Kudos
Highlighted
Professor
Professor
6,286 Views
Registered: ‎08-14-2007

It should be possible to LOC the GTX Channels (internally on an X/Y grid) instead of the package pins.  Each GTX channel can only connect to one set of package pins, so once you locate the GTX channel, you have determined that it connects as on your board.  Then the only remaining issue is that you need to make sure that the top level VHDL ports for the GTX don't appear in the version where there is no GTX transceiver.  Otherwise as you have found already, the tools try to infer I/O buffers for those ports.

-- Gabor
Highlighted
Scholar
Scholar
6,257 Views
Registered: ‎09-16-2009

@aricblumer

 

We conditionally include GT* all the time without issues.  i.e. we instantiate N aurora cores in many of our designs. Like you we use non-project TCL flows, and only LOC the GT* pins (not the transceivers)

 

In our flow I think this works because in the (non-instanced) case, we don't reference those GT* pins at all.  Those ports don't exists at the top-level FPGA - and we don't reference the LOC of the (unused) GT* at all.

 

So, if you're reconfiguring the same FPGA (i.e. sharing the exact same top-level FPGA) but have multiple use models - some with a specific GTX, some without - then it's not quite that simple of sharing the same FPGA.v, and FPGA.xdc file.  You'd need to somehow conditionally include those extra ports, and XDC constraints. You can't just feed in a new parameter to the synthesis and go.

 

An alternative as others here have suggested/hinted at is to yes, always include those pins, and LOCs.  However in the 'no use' case conditionally instantiate a dummy tie-off GTX, instead of whatever nominal function is used.  There was some AR note (I'm thinking Virtex5 days) where we were required for some reason or other to create "tie off GTx" (Think it had something to do with refclk routing).  The tie-off GTX module took a little grunt work to flesh out, but wasn't difficult.

 

Good luck.

 

Mark

 

Highlighted
Guide
Guide
6,224 Views
Registered: ‎01-23-2009

The ideal solution would be to ensure that the top level ports for the unused GTs don't exist. I am not a VHDL expert, but I am pretty sure there is no syntax for having/not having a top level port depending on a generic.

 

One option (and I again, I don't know if this is possible or even works in your system), if there are a variable number of GTs (but always at least one), then maybe you can define the top level ports as a vector of GT pins, and change the size of the vector using a generic (from a package?). If so, you may be able to find a way to always have only ports for the GT pins you are using and no ports for those that don't.

 

If you can't do this, then you may not have a clean solution. If the port exists at the top level, even if there is no logic connected to it, the tools cannot optimize out the port. I am pretty sure you won't be able to generate a bitstream for it if there is no PACKAGE_PIN for the port - even if there is no logic connected to it.

 

The only other thing I can think of that you can try is to use the "set_logic_unconnected" command on the unused ports. This command is normally used only for hierarchical design and Out-Of-Context modules, but you can always try it to see if it will work at the top level.

 

Avrum

0 Kudos
Highlighted
Observer
Observer
2,855 Views
Registered: ‎02-02-2012

Hmm interesting reading!

 

I'm suffering from the same problem and had another approach 2017.2. I can get it working statically but not yet dynamically. I simply make sure there are no io buffers attached to the ports with this attribute. 

 

entity top is

port(t

  txp: out std_logic_vector (3 downto 0); 

  txn : out std_logic_vector(3 downto 0));

  rxp: in std_logic_vector (3 downto 0); 

  rxn : in std_logic_vector(3 downto 0)

);

attribute io_buffer_type : string;

attribute io_buffer_type of txp,txn,rxp,rxn: signal is “none”;

end top;

 

--> vivado treats its as regular ports but does not want to place them (they are thrown away) exactly what we want.

 

Now if i could get this attribute set using tcl based on a toplevel generic then i would have what i want. But i couldn't get that to work.... any ideas on this?

 

0 Kudos