VHDL Syntax Review

advertisement
VHDL Syntax Review
Matthew Murach
Basic code layout
 Define data types (library declarations)
o IEEE_std_logic_1163.all defines bit type (0,1,U,X,-,H,L)
o IEEE_std_logic_unsigned.all defines arithmetic for unsigned numbers
 Define user packages
o Custom packages Altera,Xilinx, or you come up with
So…
Library ieee;
Use ieee.std_logic_1163.all;
Use ieee.std_logic_unsigned.all;
Use work.p1_pack.all;
-- Use IEEE libraries note that the double
-- hyphen is used for commenting
-- Your custom package can define types for
-- example as well as constants
 Define the black box (entity declaration)
o What are the inputs and outputs
o What should be the name of this component
o Example 1-bit adder
o Needs three inputs (one bit for operands a and b and the carry c)
o Needs two outputs (sum and the carry bit)
o Clock and enable (optional if you want to use synchronous design)
So….
Entity one_bit_add is
Port(
A : in std_logic;
B : in std_logic;
Cin : in std_logic;
S : out std_logic;
Cout : out std_logic;
Clk : in std_logic;
En : in std_logic
);
end one_bit_add;
A
S
B
Cout
Cin
?
clk
 Well, what is in the box…(architecture section)
o Recall from logic design that the output can be computed as follows
S  A  B  Cin
Cout  AB  BCin  ACin
(1.1)
o The two outputs can be solved independently (two different trees of logic)
o So use two process directives
o Declare the architecture section as follows:
Archtecture struct of one_bit_add is
-- start defining the black box
--declare signals and sub-components here
Begin
--start processes
Sum : process(clk,en)
-- clk for sync operation or use process(a,b,cin) for
async
--declare variables for this process
Begin
If clk = ‘1’ and en = ‘1’ and clk’event then
--capture clk on the rising edge
S <=a xor b xor c; -- logic
End if;
End process;
Begin
--start processes
Carry : process(clk,en)
-- clk for sync operation or use process(a,b,cin) for
async
--declare variables for this process
Begin
If clk = ‘1’ and en = ‘1’ and clk’event then
--capture clk on the rising edge
Cout <=(a and b) or (b and c) or (a and c);
-- logic
End if;
End process;
End struct;
-- Note that the sensitivity list tells the process when to trigger. In the synchronous case
-- the operation only happens when the clk pulse is received. Likewise for the
-- asynchronous case, the answer is only re-evaluated on a changing input signal.
Differences between variables and signals
Signals are global (wire-like). That is that a signal can be used between processes. Note
that it takes one delay unit for an update to occur (or one clock cycle in synchronous
circuits). One one process may drive a signal, however multiple processes can read that
signal. Signal assignment is concurrent. The following will swap A and B’s values
A  B;
B  A;
is equal to
B  A;
A  B;
(1.2)
Variables are local (register-like). Updates are immediate and the variable can be read
and written several times in a clock. Variable assignment is sequential.
A : B;
C : A;
is NOT equal to
C : A;
A : B;
(1.3)
In the first case C gets B’s value. In the second case C gets A’s original value.
Components
Up to now, designs have been relatively simple enough to allow for the use of one VHDL
file. But what if your design is complex and has multiple logic units. Component
instancing allows you to use the same logic several times. For the previous case, a
multiple bit adder might be preferred. To create this first examine the figure below.
A(3 downto 0)
B(3 downto 0)
C(3 downto 0)
S(4 downto 0)
Figure 1. 4-bit adder.
The four bit adder can be implemented using the one bit adder created above. Note that 2
control regions exist. The fourth adder is slightly different since its carry shows up at the
output.
Library ieee;
Use ieee.std_logic_1164.all;
Entity master is
Port (a: IN std_logic_vector(3 downto 0);
b: IN std_logic_vector(3 downto 0);
s: OUT std_logic_vector(4 downto 0);
ck, en : IN std_logic);
End master;
Architecture struct of master is
-- Declare Signals
Signal c: std_logic_vector(3 downto 0);
-- Declare Components note that component declaration is similar to ---- entity declaration
Component one_bit_add is
Port(
A : in std_logic;
B : in std_logic;
Cin : in std_logic;
S : out std_logic;
Cout : out std_logic;
Clk : in std_logic;
En : in std_logic);
end component;
Begin
-- assign defaults
c(0) <= ‘0’;
-- Clearly the first carry in is zero
-- For generate loops
GI : for i in 0 to 3 Generate
G1 : if (i /= 3) Generate
cell : one_bit_add port map (A(i), B(i), C(i), S(i),
C(i+1), clk,en);
End Generate G1;
G2 : if (i = 3) Generate
cell : one_bit_add port map (A(i), B(i), C(i), S(i),
S(i+1), clk,en);
End Generate G2;
End Generate GI;
End Struct;
Download