Foundation Express works with one or more designs. Each entity (and architecture) in a VHDL description is translated to a single design in Foundation Express. Designs can also originate from formats other than VHDL, such as equations, Programmable Logic Arrays (PLAs), state machines, other HDLs, or netlists.
A design can contain instances of lower-level designs, connected by nets (signals) to the lower-level design's ports. These lower-level designs can consist of other entities from a VHDL design, designs represented in another Xilinx format, or cells from a technology library. By instantiating designs within designs, you create a hierarchy.
Hierarchy in VHDL is specified by using component declarations and component instantiation statements. To include a design, you must specify its interface with a component declaration. You can then create an instance of that design by using the component instantiation statement.
If your design consists only of VHDL entities, every component declaration statement corresponds to an entity in the design. If your design uses designs or technology library cells not described in VHDL, create component declarations without corresponding entities. You can then use Foundation Express to associate the VHDL component with the non-VHDL design or cell.
To simulate your VHDL design, you must provide entity and architecture descriptions for all component declarations.
VHDL includes constructs to use existing hardware components. These structural constructs can be used to define a netlist of components.
The following sections describe how to use components and how Foundation Express configures these components.
You must declare a component in an architecture or package before you can use (instantiate) it. A component declaration statement is similar to the entity specification statement described earlier, in that it defines the component's interface.
The syntax for a component declaration follows.
component identifier
[ generic( generic_declarations ) ]
[ port( port_declarations ) ]
end component ;
where identifier is the name of this type of component, and the syntax of generic_declarations and port_declarations is the same as defined previously for entity specifications.
The following example shows a component declaration of a Two-Input AND gate.
component AND2
port(I1, I2: in BIT;
O1: out BIT);
end component;
The following example shows a component declaration statement that uses a generic parameter.
component ADD
generic(N: POSITIVE);
port(X, Y: in BIT_VECTOR(N-1 downto 0);
Z: out BIT_VECTOR(N-1 downto 0);
CARRY: out BIT)
end component;
Although the component declaration statement is similar to the entity specification, it serves a different purpose. The component declaration is required to make the design entity AND2 or ADD usable, or visible, within an architecture. After a component is declared, it can be used in a design.
A declared component can come from the same VHDL source file, from a different VHDL source file, from another format such as Electronic Data Interchange Format (EDIF) or state table, or from a technology library. If the component is not in one of the current VHDL source files, it must already be compiled by Foundation Express.
When Foundation Express compiles a design that uses components, Foundation Express searches by name for previously compiled components in the following order.
Foundation Express checks for consistency among its VHDL entities. For other entities, the port names are taken from the original design description.
The bit widths of each port must also match. Foundation Express verifies matching for VHDL components, because the port types must be identical. For components from other sources, Foundation Express checks when linking the component to the VHDL description.
The component instantiation statement instantiates and connects components to form a netlist (structural) description of a design. A component instantiation statement can create a new level of design hierarchy.
The syntax of the component instantiation statement follows.
instance_name : component_name
[ generic map (
generic_name => expression
{ , generic_name => expression }
) ]
port map (
[ port_name => ] expression
{ , [ port_name => ] expression }
);
instance_name is the name of this instance of component type component_name.
The optional generic map assigns nondefault values to generics. Each generic_name is the name of a generic, exactly as declared in the corresponding component declaration statement. Each expression evaluates to an appropriate value.
The port map assigns the component's ports to connections. Each port_name is the name of a port, exactly as declared in the corresponding component declaration statement. Each expression evaluates to a signal value.
Foundation Express uses the following two rules to decide which entity and architecture to associate with a component instantiation.
When you instantiate a component with generics, you can map generics to values. A generic without a default value must be instantiated with a generic map value.
For example, a four-bit instantiation of the component ADD in the following example might use the following generic map.
U1: ADD generic map (N => 4)
port map (X, Y, Z, CARRY...);
The port map assigns component ports to actual signals; it is described in the next section.
You can specify port connections in component instantiation statements with either named or positional notation.
The next example shows the notation for the U5 component instantiation statement in the example that follows the next example.
EU5: or2 port map (O => n6, I1 => n3, I2 => n1);
-- Named association
U5: or2 port map (n3, n1, n6);
-- Positional association
When you use positional association, the instantiated port expressions (signals) must be in the same order as the declared ports.
The following example shows a structural (netlist) description for the COUNTER3 design entity.
architecture STRUCTURE of COUNTER3 is
component DFF
port(CLK, DATA: in BIT;
Q: out BIT);
end component;
component AND2
port(I1, I2: in BIT;
O: out BIT);
end component;
component OR2
port(I1, I2: in BIT;
O: out BIT);
end component;
component NAND2
port(I1, I2: in BIT;
O: out BIT);
end component;
component XNOR2
port(I1, I2: in BIT;
O: out BIT);
end component;
component INV
port(I: in BIT;
O: out BIT);
end component;
signal N1, N2, N3, N4, N5, N6, N7, N8, N9: BIT;
begin
u1: DFF port map(CLK, N1, N2);
u2: DFF port map(CLK, N5, N3);
u3: DFF port map(CLK, N9, N4);
u4: INV port map(N2, N1);
u5: OR2 port map(N3, N1, N6);
u6: NAND2 port map(N1, N3, N7);
u7: NAND2 port map(N6, N7, N5);
u8: XNOR2 port map(N8, N4, N9);
u9: NAND2 port map(N2, N3, N8);
COUNT(0) <= N2;
COUNT(1) <= N3;
COUNT(2) <= N4;
end STRUCTURE;
When you use a structural design style and you want to instantiate logical components, Xilinx provides generic technology library GTECH for this purpose. This generic technology library contains technology independent logical components, such as the following.
You can use these simple components to create technology independent designs. The following example shows how an N-bit ripple-carry adder can be created from N one-bit adders.
library GTECH;
use gtech.gtech_components.all;
entity RIPPLE_CARRY is
generic(N: NATURAL);
port(A, B: in BIT_VECTOR(N-1 downto 0);
CARRY_IN: in BIT;
SUM: out BIT_VECTOR(N-1 downto 0);
CARRY_OUT: out BIT;);
end RIPPLE_CARRY;
architecture TECH_INDEP of RIPPLE_CARRY is
signal CARRY: BIT_VECTOR(N downto 0);
begin
CARRY(0) <= CARRY_IN;
GEN: for I in 0 to N-1 generate
U1: GTECH_ADD_ABC port map(
A => A(I),
B => B(I),
C => CARRY(I),
S => SUM(I),
COUT => CARRY(I+1));
end generate GEN;
CARRY_OUT <= CARRY(N);
end TECH_INDEP;