modelsim doesn't complain when i instantiate the clock buffer like this:
Code:
library axcelerator;
use axcelerator.hclkbuf;
---
inst_hclkbuf : entity axcelerator.hclkbuf
port map (
pad => clk_in,
y => clk_out
);
when i go to synthesis using synplify, it errors out with the message: Instantiated entitty axcelerator.hclkbuf has not been analyzed.
if i change to whats below it works fine.
Code:
library axcelerator;
use axcelerator.hclkbuf;
---
component hclkbuf
port (
pad : in std_logic;
y : out std_logic
);
----
inst_hclkbuf : hclkbuf
port map (
pad => clk_in,
y => clk_out
);
synplify is linked to the axcelerator library properly and it shows up under the design hierarchy. it appears it should compile in the proper order. any ideas?
Modelsim doesn't complain because at some point you must have compiled the hclkbuf entity into the axcelerator library. That could have been two years ago, but as long as it can find the axcelerator library and the axcelerator.hclkbuf component it is happy. Synthesis though requires you to start with a clean slate on every run. Every entity needs to be defined in some source file prior to the point where you try to instantiate it. If you don't you get the error that you reported.
However, when you declare a component, what you're basically doing is creating an IOU of the entity. A component declaration basically says that the entity declaration can come later (or it may have already been compiled also), here is what it will look like when it does come along, so don't complain (i.e. flag an error) just yet. The reason is that when analyzing a source file, it simply needs to know the signal types and check that they match with the signals that you attach to the ports. It can do that when you declare the component or if it has already compiled the entity. In the end you will still need the entity and the architecture. Given only the component declaration, synthesis temporarily treats it like a black box...but in order to get a bitstream that programs a device that 'black box' needs to be implemented by something whether it is from your code or from some vendor's code.
The advantage of using a component is that if you declare them for every entity in your code, then there is absolutely no 'compile order' for the source files. They can be analyzed in any order. Sounds nice, but there are drawbacks and that 'compile order' is not that hard to get right, you only do it once (or whenever you add new files to the project) so it's not usually
that big of an advantage.
The drawback of using components ('specially in the architecture of the code that is to instantiate that component) is that you have to manually maintain the source that declares the component to make it be the same as the entity. If there is a mismatch, the error messages that pop out of the tools come out further downstream and can be less than enlightening. In short, it's more tedious to find and fix the problem. Consider this scenario:
- Create your own wonderful reusable widget
- Use that widget in several source files (maybe in several projects)
- Change the interface to that widget by adding some additional signal or generic
Now you have to manually search for every instance where you used the widget (and therefore declared the component) to update the component definition that you have to add the additional signal or generic. Miss a file and it will analyze just fine, but get caught further dowstream with some form of 'missing component' error because you didn't fulfill the IOU because your entity doesn't match the component. In contrast, if you use direct entity instantiation, you simply 'compile all' and each source file that instantiates the component will be flagged and easily fixed. Much easier.
If you do choose to use component declarations anyway, the better method is to create a package and put the component declaration in the package which is preferably in the same file as the entity. Now when the interface changes, the
single component declaration and the entity can be edited together in one file rather than many files. The code that instantiates the widget simply has a 'use work.my_widget.all' statement in it. Still better to use direct entity instantiation in synthesizable code but a dramatic improvement over defining the component in the architecture.
The bottom line is that using component declarations where they are not needed (i.e. to interface to vendor IP that you don't get source code for), you create a one time advantage (i.e. no compile order). But by doing so you create the potential for obscure errors throughout the entire lifetime of that code. The choice is yours.
Kevin Jennings