Chapter start Previous page Next page 10.9 Other DeclarationsA declaration is one of the following [VHDL LRM4]: declaration ::= type_declaration | subtype_declaration | object_declaration | interface_declaration | alias_declaration | attribute_declaration | component_declaration | entity_declaration | configuration_declaration | subprogram_declaration | package_declaration | group_template_declaration | group_declaration I discussed entity, configuration, component, package, interface, type, and subtype declarations in Sections 10.5-10.8. Next I shall discuss the other types of declarations (except for groups or group templates [VHDL 93LRM4.6-4.7], new to VHDL-93, that are not often used in ASIC design). 10.9.1 Object DeclarationsThere are four object
classes in VHDL: constant, variable, signal, and file [VHDL
LRM 4.3.1.1-4.3.1.3]. You
use a constant declaration, signal declaration, variable declaration, or
file declaration together with a type. Signals can only be declared in the
declarative region (before the first You may assign an (explicit)
initial value when you declare a type. If you do not provide initial values,
the (implicit) default initial value of a type or subtype entity Initial_1 is end; architecture Behave of Initial_1 is type Fahrenheit is range 32 to 212; -- Default initial value is 32. type Rainbow is (R, O, Y, G, B, I, V); -- Default initial value is R. type MVL4 is ('X', '0', '1', 'Z'); -- MVL4'LEFT = 'X'. -begin end; The details of initialization and assignment of initial values are important--it is difficult to implement the assignment of initial values in hardware--instead it is better to mimic the hardware and use explicit reset signals. Here are the formal definitions of constant and signal declarations: constant_declaration ::= constant identifier {, identifier}:subtype_indication [:= expression] ; signal_declaration ::= signal identifier {, identifier}:subtype_indication [register|bus] [:=expression]; I shall explain the use of
signals of kind entity Constant_2 is end; library IEEE; use IEEE.STD_LOGIC_1164.all; architecture Behave of Constant_2 is constant Pi : REAL := 3.14159; -- A constant declaration. signal B : BOOLEAN; signal s1, s2: BIT; signal sum : INTEGER range 0 to 15; -- Not a new type. signal SmallBus : BIT_VECTOR (15 downto 0); -- 16-bit bus. signal GBus : STD_LOGIC_VECTOR (31 downto 0); bus; -- A guarded signal. begin end; Here is the formal definition of a variable declaration: variable_declaration ::= [shared] variable identifier {, identifier}:subtype_indication [:= expression] ; A shared variable can be used
to model a varying quantity that is common across several parts of a model,
temperature, for example, but shared variables are rarely used in ASIC design.
The following examples show that variable declarations belong inside a library IEEE; use IEEE.STD_LOGIC_1164.all; entity Variables_1 is end; architecture Behave of Variables_1 is begin process variable i : INTEGER range 1 to 10 := 10; -- Initial value = 10. variable v : STD_LOGIC_VECTOR (0 to 31) := (others => '0'); begin wait; end process; -- The wait stops an endless cycle. end; 10.9.2 Subprogram DeclarationsVHDL code that you
use several times can be declared and specified as subprograms (functions
or procedures) [VHDL LRM2.1]. A
function is a form of expression, may only use parameters of mode subprogram_declaration ::= subprogram_specification ; ::= procedure identifier|string_literal [(parameter_interface_list)] | [pure|impure] function identifier|string_literal [(parameter_interface_list)] return type_name|subtype_name; Here are a function and a procedure declaration that illustrate the difference: function add(a, b, c : BIT_VECTOR(3 downto 0)) return BIT_VECTOR is -- A function declaration, a function can't modify a, b, or c. procedure Is_A_Eq_B (signal A, B : BIT; signal Y : out BIT); -- A procedure declaration, a procedure can change Y. Parameter names in subprogram
declarations are called formal parameters (or formals). During a call to
a subprogram, known as subprogram invocation, the passed values are actual
parameters (or actuals). An impure function, such as the function A subprogram declaration is optional, but a subprogram specification must be included in the subprogram body (and must be identical in syntax to the subprogram declaration--see BNF [10.19]): subprogram_body ::= subprogram_specification is {subprogram_declaration|subprogram_body |type_declaration|subtype_declaration |constant_declaration|variable_declaration|file_declaration |alias_declaration|attribute_declaration|attribute_specification |use_clause|group_template_declaration|group_declaration} begin {sequential_statement} end [procedure|function] [identifier|string_literal] ; You can include a subprogram
declaration or subprogram body in a package or package body (see Section 10.6)
or in the declarative region of an entity or function subset0(sout0 : in BIT) return BIT_VECTOR -- declaration -- Declaration can be separate from the body. function subset0(sout0 : in BIT) return BIT_VECTOR is -- body variable y : BIT_VECTOR(2 downto 0); begin if (sout0 = '0') then y := "000"; else y := "100"; end if; return result; end; procedure clockGen (clk : out BIT) -- Declaration procedure clockGen (clk : out BIT) is -- Specification begin -- Careful this process runs forever: process begin wait for 10 ns; clk <= not clk; end process; end; One reason for having the optional (and seemingly redundant) subprogram declaration is to allow companies to show the subprogram declarations (to document the interface) in a package declaration, but to hide the subprogram bodies (the actual code) in the package body. If a separate subprogram declaration is present, it must conform to the specification in the subprogram body [VHDL 93LRM2.7]. This means the specification and declaration must be almost identical; the safest method is to copy and paste. If you define common procedures and functions in packages (instead of in each entity or architecture, for example), it will be easier to reuse subprograms. In order to make a subprogram included in a package body visible outside the package, you must declare the subprogram in the package declaration (otherwise the subprogram is private). You may call a function from any expression, as follows: entity F_1 is port (s : out BIT_VECTOR(3 downto 0) := "0000"); end; architecture Behave of F_1 is begin process function add(a, b, c : BIT_VECTOR(3 downto 0)) return BIT_VECTOR is begin return a xor b xor c; end; begin s <= add("0001", "0010", "1000"); wait; end process; end; package And_Pkg is procedure V_And(a, b : BIT; signal c : out BIT); function V_And(a, b : BIT) return BIT; end; package body And_Pkg is procedure V_And(a,b : BIT; signal c : out BIT) is begin c <= a and b; end; function V_And(a,b : BIT) return BIT is begin return a and b; end; end And_Pkg; entity F_2 is port (s: out BIT := '0'); end; use work.And_Pkg.all; -- use package already analyzed architecture Behave of F_2 is begin process begin s <= V_And('1', '1'); wait; end process; end; I shall discuss the two different ways to call a procedure in Sections 10.10.4 and 10.13.3. 10.9.3 Alias and Attribute DeclarationsAn alias declaration [VHDL 87LRM4.3.4, 93LRM4.3.3] names parts of a type: alias_declaration ::= alias identifier|character_literal|operator_symbol [ :subtype_indication] is name [signature] ; (the subtype indication is required in VHDL-87, but not in VHDL-93). Here is an example of alias declarations for parts of a floating-point number: entity Alias_1 is end; architecture Behave of Alias_1 is begin process variable Nmbr: BIT_VECTOR (31 downto 0); -- alias declarations to split Nmbr into 3 pieces : alias Sign : BIT is Nmbr(31); alias Mantissa : BIT_VECTOR (23 downto 0) is Nmbr (30 downto 7); alias Exponent : BIT_VECTOR ( 6 downto 0) is Nmbr ( 6 downto 0); begin wait; end process; end; -- the wait prevents an endless cycle An attribute declaration [VHDL LRM4.4] defines attribute properties: attribute_declaration ::= attribute identifier:type_name ; | attribute identifier:subtype_name ; entity Attribute_1 is end; architecture Behave of Attribute_1 is begin process type COORD is record X, Y : INTEGER; end record; attribute LOCATION : COORD; -- the attribute declaration begin wait ; -- the wait prevents an endless cycle end process; end; You define the attribute properties in an attribute specification (the following example specifies an attribute of a component label). You probably will not need to use your own attributes very much in ASIC design. attribute LOCATION of adder1 : label is (10,15); You can then refer to your attribute as follows: positionOfComponent := adder1'LOCATION; 10.9.4 Predefined AttributesThe predefined attributes
for scalar and array types in VHDL-93 are shown in Table 10.14 [VHDL 93LRM14.1]. There are two attributes,
The attribute
1. T = Type, F = Function, V = Value, R = Range. 2. any = any type or subtype, scalar = scalar type or subtype, discrete = discrete or physical type or subtype, name = entity name = identifier, character literal, or operator symbol. 3. base(T) = base type of T, T = type of T, UI = universal_integer, T(Result) = type of object described in result column. 4. Only available in VHDL-93. For 5. Or reverse for descending ranges. 7. Time T >= 0 ns. The default, if T is not present, is T = 0 ns. 9. VHDL-93 returns last value of each signal in array separately as an aggregate, VHDL-87 returns the last value of the composite signal. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|