Traditional Schematic view of design
To represent communication between design entities which are CONCURRENTLY active.
entity XOR port ( a, b : in bit; y : out bit ); end XOR; architecture nand_gates of XOR is signal s0, s1, s2: bit; component nand port ( a, b: in bit; y: out bit ); end; for all: nand use entity asic.nand2(behavioral); begin U1: nand port map ( a, b, s0 ); U2: nand port map ( a, s0, s1); U3: nand port map ( b, s0, s2); U4: nand port map ( s1, s2, y); end nand_gates;
generic map ( interface_list );
port map ( interface_list );
-- Component declarations can be done directly in an -- Architecture, but large collections of component -- declarations are better kept in a package. -- You then "get at" those declaration by naming the -- package in a USE statement. package logic_family is component And2 port ( i1, i2 : in bit; z : out bit ); end component; component And3 port ( i1, i2, i3 : in bit; z : out bit ); end component; component Nor2 port ( i1, i2 : in bit; z : out bit ); end component; component Nor3 port ( i1, i2, i3 : in bit; z : out bit ); end component; component Xor2 port ( i1, i2 : in bit; z : out bit ); end component; component Nand2 port ( i1, i2 : in bit; z : out bit ); end component; component Inverter port ( i1 : in bit; z : out bit ); end component; end logic_family; use work.logic_family.all; entity ALU_slice is port ( func_sel : in bit_vector ( 0 to 3 ); mode : in bit; X, Y, Cy_in : in bit; F : out bit; Cy_out : out bit ); end ALU_slice; architecture Structure of ALU_slice is
signal Cy_not, Ynot, Mnot : bit ; signal va, vb, vc, vd, ve, vf, vg, vh, vi, vj : bit;
begin
--note the instance labels!
end Structure;
Note the use of subscripted members of a bit vector in connecting
components.
component Nor2 port ( i1, i2 : in bit; z : out bit ); end component;
then the instantiation
U5: Nor2 port map ( za,zb,ze );
CPU: Microprocessor port map ( Address_bus => Addr, Data_bus => Data, MRQ => MemReq, IORQ => IO_Req, WR_bar => RWb, CLK => Clock, RFSH_bar => open, HALT_bar => open ) ;
Binding actual constants to formal generics is performed in exactly
the same fashion as for ports.
While ports must be connected using signals, the inputs to generics
must be constants.
Example of uses of generics in structural VHDL:
-- timing specifications -- dimensions Mem: RAM generic map ( wordsize => 16; memsize => 2**adrs'length; t_access => 15 ns; t_cycle => 25 ns );
Instantiation of Regular Structures
label: for index in discrete_range
generate
concurrent_statement (s)
end generate;
The index is implicitly declared by its use in the for.
It may be referenced only within the generate block it encloses.
The discrete_range is evaluated at the build step. It may
be the range attribute of some signal, or may be of the form:
It must always be possible to evaluate constant expressions at
the BUILD step.
label: if condition_expression then generate
concurrent_statement (s)
end generate;
Here the condition_expression is evaluated during the BUILD
step, and must be a constant expression -- although the constant
expression will probably contain one or more generics in it.
Iteration
Example: An N-bit wide shift register is being assembled from
one bit Shift_Slice cells.
signal C : bit_vector ( 0 to REGSIZE-1 ); -- where REGSIZE is a generic parameter for the design begin sreg: for i in 0 to REGSIZE-1 generate s0: if i = 0 generate t0: Shift_Slice generic map (tprop) port map (clk,enb,S_in, C(i), Q(i)); end generate; si: if i > 0 and i < REGSIZE-1 generate ti: Shift_Slice generic map (tprop) port map (clk,enb,C(i-1), C(i), Q(i)); end generate; sn: if i = REGSIZE-1 generate tn: Shift_Slice generic map (tprop) port map (clk,enb,C(i-1), S_out, Q(i)); end generate; end generate; -- for loop . . . . . end; Notes: The index i exists only inside the loop, and cannot be redefined. No explicit declaration of the index is required. Every for - generate and if-generate statement must have a label. Remember that every component instantiation must have a label, too.
Recursion
Iteration is the common form for instantiation of regular
structures, but recursion can be useful, too.
Example
entity decoder is generic (N : integer); port ( sel : bit_vector ( 1 to N ); Y : bit_vector (1 to 2**N) ); end decoder; architecture recursive_form of decoder is signal nsel : bit; component and2 port (i1,i2: bit; y: out bit); end component; omponent inverter port (i1: bit; y: out bit); end component; component decoder generic ( n : integer ); port (sel : bit_vector; y: out bit_vector); end component; begin inv: inverter port map (sel(N), nsel); ase: if N=1 generate Y(1) <= sel(1); Y(2) <= nsel; end generate; recurse: if N>1 generate b1: block signal temp : bit_vector ( 1 to 2**(N-1) ); begin dcd: decoder generic map (N-1) port map (sel(1 to N-1), temp); drv: for i in 1 to 2**(N-1) generate s1: and2 port map (temp(i),sel(N),Y(2*(i-1)+1) ); s2: and2 port map (temp(i), nsel , Y(2*i) ); end generate; end block; end generate; end recursive_form;
Example:
component Inverter component And3 component Xor2. . . for U7 : Inverter use entity Work.Invert ( DF_Arch); for U1, U2: And3 use entity TTL.And3 (DF_Arch); for others: And3 use entity LSTTL.And3 (DF_Arch); for all : Xor2 use entity STTL.Xor2 (DF_Arch);. . . begin -- the architectural body Use of Port Maps and Generic Maps in Configuration Specification The entities to be used for a component may not match exactly. The names of the component ports do not have to match the names used in the entity interface definition, and some of the ports of the entity may not be used. Example: entity acia is port ( -- System side data : inout byte; address : in adrs_vector; irq : out bit; bus_busy: inout bit; bus_req: out bit; data_valid: inout bit; -- Asynchronous side xmit : out bit; recv : in bit; r_strobe: in bit; async_clk: in bit ); end acia ; component sys_slot port ( -- Asynchronous side recv : in bit; strobe: in bit; -- System side D : inout byte; A : in adrs_vector; IRQ : out bit; busy: inout bit; rq: out bit; dav: inout bit ); end component; -- Now the configuration is given by for slot1, slot2 : sys_slot use entity std_cell.acia(n3703); port map (-- System side data => D, address => A, irq => IRQ, bus_busy => busy, bus_req => rq, data_valid => dav, -- Asynchronous side xmit => OPEN, recv => recv, r_strobe => strobe, async_clk => OPEN );
library ieee; use ieee.std_logic_1164.all; entity mem_board is port ( data : inout std_logic_vector; address: in std_logic_vector; nOE, nWR : in std_logic ); end mem_board; architecture S1 of mem_board is signal selectbits : std_logic_vector(0 to 1); signal csel : std_logic_vector(0 to 3); signal mem_adrs : std_logic_vector(0 to 17); component ram port ( d : inout std_logic; adrs : in std_logic_vector; CS,nOE,nWR : in std_logic); end component; begin assert selectbits'length + mem_adrs'length = address'length report "Address lines to/inside Memboard do not match." severity ERROR; D: for i in data'range generate A: for j in csel'range generate Uxy: ram port map (data(i), mem_adrs, csel(j), nOE, nWR); end generate; -- for j end generate; -- for i end S1; configuration FGD of mem_board is for S1 for all: ram use entity Fujitsu.Generic_Ram(Dynamic); end for; end for; end FGD; use work.all; configuration struct1 of TLC_TEST is for Test -- where the outermost entity is TLC_Test -- and Test is an architecture implementing it. for Controller : TLC use entity work.Traffic_Light_Controller (Structure1); -- instance Controller of component TLC in -- TLC_TEST(Test) is to have this entity in it. for Structure1 -- specifying the timer section of this arch. for Timer_Struct : Timer_Section use entity work.Timer (Behavior); end for; end for; end for; end for; end struct1;