Why are ports redefined when using components? - vhdl

I'm learning VHDL and find something confusing. Suppose you have the following entity:
entity alu32 is
port(a, b : in STD_LOGIC_VECTOR(31 downto 0);
alucontrol : in STD_LOGIC_VECTOR(2 downto 0);
result : buffer STD_LOGIC_VECTOR(31 downto 0);
zero : out STD_LOGIC);
end alu32;
When using it as a component in another entity's architecture, it's defined like this:
component alu32
port(
a, b : in STD_LOGIC_VECTOR(31 downto 0);
alucontrol : in STD_LOGIC_VECTOR(2 downto 0);
result : buffer STD_LOGIC_VECTOR(31 downto 0);
zero : out STD_LOGIC
);
end component;
My question is, why do we redefine the port? It seems like a pointless exercise since it's exactly the same as in the entity declaration. Why wasn't VHDL design to allow you to simply use a component like this:
component alu32;

You can, since VHDL-93. You can instantiate using
Alu_0: entity work.alu32
port map (
...
);
In this snippet, you can replace work for the VHDL library of the component you want to instantiate, work is always the current library the VHDL source resides in.
Why use the component declaration? First, they are required if what you want to instantiate is not VHDL, such as Verilog, IP cores and netlist. Second, using configuration allow to change port/entity binding, but you need component declaration for that.

Essentially the language designers were looking forward as carefully as they could, to a world that ... didn't quite happen that way.
The idea of a component declaration was that it defines exactly what is expected when you instantiate it, thus an entity/architecture that uses these components is self-consistent and can be compiled and to some extent tested as an independent task from the components it uses - perhaps even before those components are written.
Bill Lynch's comment is relevant here, and easy to forget today : when compilation took a thousand times longer, this was a big productivity win
Later, when you build the overall design, that component is searched for in a library of components, and either an exactly matching entity is found (default configuration), or a specific component is selected by a configuration statement. Or elaboration fails, reporting the mismatch as an error - no chance of creating a design with a part that doesn't quite fit. The library could contain a wide range of "alu32" components with different characteristics for different purposes (fast, small, with/without floating point, etc). This happens at "elaboration", roughly the same as the link stage in software, when (hopefully) the right entity/arch is found, and its ports checked against those of the component. This was a natural way to see design evolving for designers who grew up with "The TTL Data Book" - a library of physical building blocks in the form of TTL ICs.
However, in a typical use case today, we don't use libraries of components to such a great extent, so the "alu32" in your example is probably another file in the same project, compiled into your "work" library.
And in that case, the shorter, simpler "direct entity instantiation" (introduced in 1993) from Jonathan Drolet's answer is the correct approach. Downside? It does mean you have to write - and successfully compile - the "alu32" entity before you can syntax check the top level design (though you can write the architecture later, before elaboration).

IEEE Std 1076-2008, 6.8 Component declarations
A component declaration declares an interface to a virtual design entity that may be used in a component instantiation statement. A component configuration or a configuration specification can be used to associate a component instance with a design entity that resides in a library.
3.4 Configuration declarations
In certain cases, however, it may be appropriate to leave unspecified the binding of component instances in a given block and to defer such specification until later.
A component declaration is like a Function prototype. A generic map or port map aspect is part of a binding indication.
From Annex I:
binding: The process of associating a design entity and, optionally, an architecture with an instance of a component. A binding can be specified in an explicit or a default binding indication. (3.4, 7.3.2, 7.3.3, 14.4.3.3, 14.5.4)
As an example of where you'd want to consider component declarations used with configuration declarations, a design where internal blocks have the same interface:
component sbox
port (
B: in std_logic_vector (1 to 6);
S: out std_logic_vector (1 to 4)
);
end component;
They are actually distinct and you use more than one:
S1: sbox
port map (
B => ExK(1 to 6),
S => PO(1 to 4)
);
S2: sbox
port map (
B => ExK(7 to 12),
S => PO(5 to 8)
);
The enclosing entities are otherwise identical (dslice).
You can specify which entity is used where during elaboration:
configuration behave_config of des is
for behave
for DSLICE0: dslice
use entity work.dslice(behave);
for behave
for S1: sbox
use entity work.sbox1(behave);
end for;
for S2: sbox
use entity work.sbox2(behave);
end for;
end for;
end for;
...
The DES encryption algorithm in this instance can be described as hardware in four sections differentiated by substitution box contents and external interconnections.
This design model demonstrates the hardware nature of the Digital Encryption Algorithm found in the Digital Encryption Standard (FIPS Pub 46, single DES). You can take a close look at this link - vhdl_des.tar.gz.
And for synthesis or simulation tools that don't support configuration the alternative is to uniquify the blocks containing the instantiated entities, in this case increasing the size of the design description by almost a factor of four along with the increased maintenance and hazards of needless replication.

Related

Are there any disadvantages to using '.all' in a 'use' clause?

Like the title says, why would you not just always use 'mylib.mypkg.all'? In some code I see things like:
use mylib.mypkg.func1;
use mylib.mypkg.func2;
When I would think I could just do:
use mylib.mypkg.all
Is there an advantage or purpose in only selecting certain functions or components besides just being explicit?
I'm new to VHDL and 'use' seems very similar to '#include' from C for me, so correct me if that is a poor way of thinking.
I've searched other questions and elsewhere online and I can't seem to find any reason why I shouldn't just always use '.all'.
Using .all on a use clause will make everything in that package visible. Which may be fine.
But as an engineer picking a design up, imagine my horror when I see this:
use lib.pkg1.all;
use lib.pkg2.all;
use lib.pkg3.all;
use lib.pkg4.all;
use lib.pkg5.all;
use lib.pkg6.all;
use lib.pkg7.all;
...and so on
And then see this:
if some_sig = some_constant_from_a_package then
Its quite confusing keeping track of whats from which package, and then which package I need to modify, and I end up constantly using search to find where some constant is actually defined.
Luckily, VHDL allows direct referencing to make everyone's life easier. So you can do this:
if some_sig = lib.pkg4.some_constant then
It makes keeping track of where everything is much easier.
But sometimes its just easier to do a .all include. Certain operators are defined implicitly for all types. Which can lead to interesting and confusing errors
use lib.pkg.some_type;
signal a,b : some_type;
...
if a = b then
Here, you'll get an error because the "=" function that got declared implicitly with the type doesnt get included, and hence the compiler cannot see the function. You will need to either use a .all use, import the "=" function:
use lib.pkg."=";
or a direct reference:
if a lib.pkg."=" b then
There is a final problem - invisibility. If two packages declare items with the same name and you include both packages, the compiler doesn't know which one you mean and will make them both invisible. The most common way to do this is with the following includes:
use ieee.numeric_std.all;
use ieee.std_logic_arith.all;
Here, the vhdl standard package numeric_std and non-standard std_logic_arith both define signed and unsigned types. And hence the following will throw a syntax error:
signal a : unsigned(7 downto 0);
To get around this, you will need to directly reference which type you meant:
signal a : ieee.numeric_std.unsigned(7 downto 0);
signal b : ieee.std_logic_arith.unsigned(7 downto 0);
Remember, these types are not the same and hence not directly compatible.

VHDL-2008 external names: reference verilog net?

Is it possible to use VHDL-2008 hierarchical references / external names to reference Verilog nets? Questa Sim (10.6c) stops the simulation with this error message:
vsim-8509: The object class "SIGNAL" of "dut_i.my_net" is different from the class "net" of the denoted object.
Here's the VHDL code that fails:
alias my_alias is << signal dut_i.my_net : std_logic >>;
According to the Questa User Manual:
Questa SIM supports the IEEE 1076-2008 standard “external name” syntax
that allows you to make hierarchical references from VHDL to VHDL.
Currently, these references can cross Verilog boundaries, but they
must begin and end in VHDL.
Thus, the answer is no.
Questa does provide a set of Signal Spy procedures to access your Verilog signals via string names. You must also turn on optimization visability to access these signals since the strings are not parsed until run-time.

declaration of an std_logic_vector having a variable size in VHDL

In a structural description using the vhdl language, I want to decalare an std_logic_vector having a variable size. This size is determined by another component in the same structure. How Can I proceed.
Create a package with a constant assigned to the desired length, and use this constant when declaring the port length on the component and the std_logic_vector in the structural code. This way the length will automatically match.
I would use a generic. Generic parameters are specified outside of the entity declaration. They are also well supported by simulators and synthesizers.

Altera Qsys and top level entity with array of std_logic_vector

I have been trying to declare my type in a separate "mytypes.vhd" file as follows:
library ieee;
use ieee.std_logic_1164.all;
package mytypes is
type my_bus_array_type is array (0 to 3) of std_logic_vector(7 downto 0);
end package mytypes;
and then define an entity as follows:
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.mytypes.all;
entity my_entity is
port(
bus_array : in my_bus_array_type;
...
);
end my_entity;
Well, this is not working. When I try to add the component to my library with the Altera Qsys tool, I get the following error:
Error: Verilog HDL or VHDL XML Interface error at my_entity.vhd(41): port "bus_array" has an unsupported type File: /home/project/my_entity.vhd Line: 41
Please note that the problem is the fact that I am trying to define inside an entity an array of standard_logic_vector, i.e. a multidimensional array. This code works correctly if I define an array of std_logic instead.
You mentioned you're using Quartus, which can be picky about using std_logic_vectors as base types for other items.
I do what I think you're after in Quartus using subtypes:
mytypes.vhd file:
library ieee;
use ieee.std_logic_1164.all;
package mytypes is
subtype BYTE_T is std_logic_vector(7 downto 0);
type BYTE_A is array (natural range <>) of BYTE_T;
type my_bus_array_type is array (0 to 3) of BYTE_T;
end package mytypes;
my_entity.vhd file:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.mytypes.all
entity my_entity is
port (
my_bus_array1 : in BYTE_A(0 to 3);
my_bus_array2 : in my_bus_array_type;
...
It's up to you whether you want to define the array range in the entity (perhaps using a generic), or in your package.
I am not an expert in VHDL but I think you have to write your code like this :
I edited : try this instead :
package mytypes is
type my_bus_array_type is array (0 to 3) of std_logic_vector(7 downto 0);
end package mytypes;
entity my_entity is
port ( my_bus_array : in my_bus_array_type;
...);
end my_entity
You have to tell the compiler to use the types you created in the mytypes package:
use work.mytypes.all
entity my_entity is
port ( my_bus_array : in my_bus_array_type;
...
I've had similar problems, and it has had to do with handling of VHDL libraries. All HDL components in Qsys will be assigned a VHDL library with the library name set to the name of the Qsys project. Packages must be accessed with library explicitly (work. in your case) and this can mess things up. That being said, usually using packages in Qsys components has worked fine for me (including accessing them with work.).
To see how Quartus assigns and compiles into libraries, check "Design units" tab in Quartus. It lists units in folders of libraries. However, I've seen that packages will not be listed here, for some reason. Also see the .qip file of your Qsys project, where you can see exactly how Quartus has assigned your HDL files into a library.
The fact that your problem doesn't appear when instantiating your code directly in the Quartus project, rather than as a Qsys component, hints of the library issue being the explanation for this.
I've only found two references on the Qsys library handling:
http://www.alteraforum.com/forum/showthread.php?t=33605
http://www.alterawiki.com/wiki/New_Qsys_Issues (see section "Unavoidable design unit collisions")
(On a side note, I often use arrays of std_logic_vector in Qsys components and never experienced a problem with that.)
What you're trying to really define is a 2D array as a port. Unfortunately, QSYS does NOT support 2D arrays. No standard Qsys interfaces support anything more than a 1 dimensional port array. Hence you'd have to break the array apart in your top level entity, export the individual ports as conduits, and then reassemble them at a higher level back into an array. This is unfortunate but true.

Why do I need to redeclare VHDL components before instantiating them in other architectures?

I've been scratching my head since my first VHDL class and decided to post my question here.
Given that I have a declared entity (and also an architecture of it) and want to instantiate it inside another architecture, why is it that I seemingly have to redeclare the "entity" (component) inside this containing architecture before instantiating it?
Isn't the compiler smart enough to match an instantiation to its architecture just by its name? Where is the need for the component declaration?
You can directly instantiate the component, if desired:
MyInstantiatedEntity : entity work.MyEntity_E
generic map (
config => whatever)
port map (
clk => signal1,
clk_vid => signal2,
...
Creating a component declaration gives you the extra ability to change what gets bound to the instantiation via a configuration specification or similar.
Back when I did my VHDL assignments back when I was in school, I was required to have all our code all in one file so I don't remember whether or not you could write one file for each module and how it was done.
That being said, you would have to declare the entity you would use when defining the behavior, if you were using it much in the same way that you would define prototypes, structures, classes and whatnot in C or C++. The difference here is that you don't have the luxury of defining header files for this "redeclaration" in VHDL (at least I don't think there is an equivalent). So it seems perfectly reasonable to me to have to do this. Note that VHDL came out when C was very common and the compilers weren't "smart enough" as they are today.
A VHDL guru might have a definitive answer for this but this is how I understand it.

Resources