Showing results for 
Show  only  | Search instead for 
Did you mean: 
Registered: ‎03-14-2018

Inference of block designs to components

Dear community,


this is not directly synthesis related, but is also relevant for elaboration for simulation, but I think this is still the best-fitting subforum for this:


Let's say I have a design which uses one or more block designs which each contain one of the standard IP cores of Vivado (2017.4). At some point in my VHDL code, I have components declared, which match the port list of the external ports of these block designs.


Vivado really leaves me confused with respect to how it infers (or fails to infer) if a block design will be used for the component or not and if so, which.


Apparently inference is possible only if the name of the component also matches the name of the BD, otherwise Vivado always failed to do that during my tests.

But now I stumbled upon a very strange problem:

- In Project A, I had written a test bench for testing a certain part of my code, where Vivado was able to automatically infer that I want to use a certain BD for a component. Inference also worked for out-of-context synthesis of the tested entity.

- In Project B, I use the entity that I could correctly simulate and synthesize in Project A in a larger context, where Vivado is also able to infer which BD to use for the component.

- In Project A, I added another test bench, where the previous test entity was instantiated multiple times within another entity. This extra entity should make no difference on BD inference, as it instantiates the same way the other entity could be instantiated before in the other test bench (+ some signal connecting). However, now the simulation is not able to infer which entity to use in the inner part of the code, while it is still able to do that for the old test bench.


How can that be? The entity where the BD component should be inferred is precisely the same, the extra "wrapper" entity seems really unspecial, but for the new test bench, inference is not working.


I know I could just force Vivado to use the block design if I generated the wrappers and told it to explicitly use these wrappers for the component instantiation, but I wonder what's the problem in the new case and I find that whole "create a wrapper only because Vivado is doing something strange which should also be working in a different way"-approach not very appealing.


Best regards

0 Kudos
2 Replies
Registered: ‎06-14-2010

Hello @id314159,


Can you please explain in more details in relation to inferencing BDs?  You are saying at one point that everything works if you create wrappers for the BDs (which is what we suggest). 

There also isn’t any indication if you are using a Vivado created wrapper or not? Therefore, we’d need more details regarding this. Thanks in advance

Kind Regards,
Anatoli Curran,
Xilinx Technical Support
Don’t forget to reply, kudo, and accept as solution.
0 Kudos
Registered: ‎03-14-2018

Hello anatoli,


thanks for your reply!


My main question was rather how Vivado does that kind of inference (block design to component) if there is no wrapper VHDL file in general than in that specific case, maybe I should have pointed that out a bit better. I assume there must be some systematic behavior by which Vivado tries to find a block design which may be used in a component, which also tells when Vivado is able to do such a thing and when it is not.


For example in the cases which I tested, Vivado needed to have a same name for the component and the block design, otherwise it would not work, even in "simple" cases. (I.e. the component instantiation is not contained within generate statements or similar.) In more complex cases, my observations were rather incoherent. (Such as component instantiation in generate statements with "explicit static" ranges or "inferable static" ranges (such as "0 to 5" (explicit) or "0 to functionOfSomething(signal'LENGTH)" (in principle inferable), which also seemed to make a difference).)


So coming back to your question/the case I was talking about (I hope I can replicate the situation, because I accepted just using the wrapper and I may have lost some of the details of when it works and when not):


First, the VHDL code/entity structure:


- Level3 entity: Here, the component "blockDesign1" is declared. (And as described above, let us assume there also is a block design with that name and a matching port, but at first no wrapper and explicit use of that wrapper for instantiation.)

Within a "for ... generate" statement that has a range that depends on a constant that is initialized by a self-written function on a signal length, that blockDesign1 component is instantiated. (So the range is not explicit but statically inferable through a function. As I said, this seemed to make a difference sometimes, at least for how the source hierarchy is displayed, if not also for synthesis/simulation elaboration.)


- Level2 entity: Here, I instantiate the Level3 entity (as entity, not component) within another "for ... generate". This time, the ranges depend only on generic parameters or constants that are initialized by simple arithmetics on generics.


- Level1 entity: Basically the same as the Level2 entity, only that I instantiate the Level2 entity here.


Level1 and Level2 are merely more than "wrapper", it is not that I left out much of the stuff that happens there. There are some signal assignments, but nothing else with components, component configurations etc., that should have any influence.


And now to the problem:

When I simulated/synthesized with the "Level2" entity as top entity (besides the testbench for the simulation, of course), Vivado had no problem assigning the block design to the component. (I could see that for example in the "instantiation tree" in the simulator view.)

Then I wanted to test the "Level1" entity as top entity and had to see that Vivado was not able to assign the component anymore, although (from my perspective) nothing really changed, only another level of entities including another generate statement was wrapped around everything. Only when I added the (auto-generated and -managed) wrapper and explicitly tell Vivado to use that for the component, it is working again.


I was just wondering about that, because all in all, my observations on when Vivado can automatically infer the block design are very incoherent now and depend on a lot of factors, which I would not expect. But as I said in the beginning, this specific example is not really what is important to me, it is rather the general rule by which Vivado attempts to infer components from block designs.

So if anybody knows something about that, that would be interesting to read, there is no need to discuss my specific case in more detail.


Best regards

0 Kudos