1. Scopul lucrrii Continuarea prezentrii unor programe VHDL pentru structuri combinaionale i secveniale, care s exemplifice utilizarea principalelor elemente de sintax ale limbajului VHDL. Verificarea funcionrii circuitelor sintetizate se face cu ajutorul mediului ModelSim.
2. Aparate necesare - calculator compatibil Pentium, minim 500MHz, minim 128MB RAM - mediul de programare ISE (Integrated Software Environment)-versiunea 8.1i, furnizat de firma Xilinx, instalat pe o platform Windows 2000 (SP2 sau SP3) sau XP. Programul poate fi instalat i pe sistemele de operare Linux sau Solaris. Se poate folosi i versiunea free ISE WebPack, care poate fi descarcat de pe site-ul firmei Xilinx. - mediul ModelSim de la Mentor Graphics, care poate fi descarcat de pe site-ul firmei Xilinx.
3. Consideraii teoretice Structura combinaional prezentat n figura 3.1 reprezint o unitate aritmetic i logic (ALU - Arithmetic Logic Unit) pentru operanzi de 8 bii. Structura este o component esenial din arhitectura unui procesor, care permite execuia operaiilor aritmetice i logice de baz. Cei doi operanzi, notai cu A i B sunt vectori de 8 bii, iar semnalul sel permite selecia celor 16 operaii posibile: 8 aritmetice i 8 logice, conform tabelului 3.1. Pentru claritate, s-au evideniat separat dou blocuri logice, unul aritmetic i unul logic, iar rezultatul corespunztor este livrat la ieire prin intermediul multiplexorului de ieire, cu ajutorul bitului cel mai semnificativ (sel(3)) din semnalul sel.
MUX Y (7:0) Unitate Unitate logica A (7:0) B (7:0) aritmetica Cin sel (2:0) sel (3) arith logic
Fig. 3.1 Structur ALU pe 8 bii care implementeaz 16 operaii 1 Tabel 4.1 sel Operaia Funcia Tipul operaiei 0000 Y <= A Transferul operandului A 0001 Y <= A + 1 Incrementarea lui A 0010 Y <= A 1 Decrementarea lui A 0011 Y <= B Transferul operandului B aritmetic 0100 Y <= B + 1 Incrementarea lui B 0101 Y <= B 1 Decrementarea lui B 0110 Y <= A + B Adunarea lui A cu B 0111 Y <= A + B + Cin Adunarea cu transport (carry) 1000 Y <= NOT A Complementarea lui A 1001 Y <= NOT B Complementarea lui B 1010 Y <= A AND B Operaia I 1011 Y <= A OR B Operaia SAU logic 1100 Y <= A NAND B Operaia I-NU 1101 Y <= A NOR B Operaia SAU-NU 1110 Y <= A XOR B Operaia SAU-EXCLUSIV 1111 Y <= A XNOR B SAU-EXCLUSIV negat
Codul VHDL este prezentat mai jos:
LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; --------------------------------------------------- ENTITY alu IS PORT (A, B: IN STD_LOGIC_VECTOR (7 DOWNTO 0); sel: IN STD_LOGIC_VECTOR (3 DOWNTO 0); Cin: IN STD_LOGIC; Y: OUT STD_LOGIC_VECTOR (7 DOWNTO 0)); END alu; --------------------------------------------------- ARCHITECTURE dataflow OF alu IS SIGNAL arith, logic: STD_LOGIC_VECTOR (7 DOWNTO 0); BEGIN WITH sel(2 DOWNTO 0) SELECT arith <= A WHEN "000", A + 1 WHEN "001", A - 1 WHEN "010", B WHEN "011", B + 1 WHEN "100", B - 1 WHEN "101", A + B WHEN "110", A + B + Cin WHEN OTHERS; WITH sel(2 DOWNTO 0) SELECT logic <= NOT A WHEN "000", NOT B WHEN "001", A and B WHEN "010", A or B WHEN "011", A nand B WHEN "100", A nor B WHEN "101", A xor B WHEN "110", not (A xor B) WHEN OTHERS; WITH sel(3) SELECT Y <= arith WHEN '0', logic WHEN OTHERS; END dataflow; 2 Codul prezentat este un cod concurent (folosim cuvntul cheie WHEN). Se folosete acelai tip de date pentru cele dou tipuri de operaii. Acest lucru este posibil datorit pachetului std_logic_unsigned din biblioteca ieee. WHEN poate aprea n dou forme: fie ntr-o form simpl ca WHEN/ELSE (de exemplu, outp <= "001" WHEN ctl = '1' ELSE), fie ntr-o form selectat ca WITH/SELECT/WHEN ca n exemplul nostru. WHEN testeaz toate combinaiile posibile, aa c pentru cele care nu ne intereseaz se folosete cuvntul cheie OTHERS. Dac nu are loc nicio aciune se poate folosi cuvntul cheie UNAFFECTED (sub forma UNAFFECTED WITH OTHERS). Observm c notaia folosit pentru atribuirea unei valori logice este '0' sau '1', ca n instruciunea: Y <= arith WHEN '0', n timp ce un vector, adic un ir de cifre binare, se reprezint ntre dou semne de citare, ca n instruciunea: A and B WHEN "010".
Un alt exemplu este bistabilul de tip D cu declanare pe front cresctor de ceas (semnalul CLK) i reset asincron (semnalul RST). Structura circuitului i tabelul tranziiilor sunt reprezentate n figura 3.2. i aici iniiem un proces concurent prin PROCESS, proces activat la modificarea semnalelor RST sau CLK, n interiorul cruia se execut instruciunea secvenial IF.
D CLK Q R D RST CLK Q CLK D R Q 0 0 0 0 1 1 x x 1 0 +
Fig. 3.2 Bistabilul D cu basculare pe front pozitiv i reset asincron
Codul VHDL este prezentat mai jos:
LIBRARY ieee; USE ieee.std_logic_1164.all; ------------------------------------------ ENTITY flipflop IS PORT (D, CLK, RST: IN STD_LOGIC; Q: OUT STD_LOGIC); END flipflop; ------------------------------------------ ARCHITECTURE behavior of flipflop is BEGIN PROCESS (CLK, RST) BEGIN IF (RST='1') THEN Q <= '0'; ELSIF (CLK'EVENT AND CLK = '1') THEN Q <= D; END IF; END PROCESS; END behavior; 3 clk Numarator BCD digit (3:0) CLK OUT
Fig. 3.3 Numrtor BCD sincron cresctor de 4 bii
Numrtorul sincron este o structur secvenial care conine mai multe bistabile. Schema din figura 3.3 reprezint un numrtor cu o singur cifr BCD, adic ieirea are 4 bii care se modific n ritmul semnalului de ceas, care este singura intrare n circuit. Secvena de la ieire este 0 1 2 ... 8 9 0 i aa mai departe. Codul VHDL ntr-o descriere comportamental ar putea fi urmtorul:
LIBRARY ieee; USE ieee.std_logic_1164.all; ----------------------------------------- ENTITY counter IS PORT (clk: IN STD_LOGIC; digit: OUT INTEGER RANGE 0 TO 9); END counter; ----------------------------------------- ARCHITECTURE counter OF counter IS BEGIN count: PROCESS (clk) VARIABLE temp: INTEGER RANGE 0 TO 10; BEGIN IF (clk'EVENT AND clk='1') THEN temp := temp + 1; IF (temp=10) THEN temp := 0; END IF; END IF; digit <= temp; END PROCESS count; END counter;
Se observ noutile care au aprut n acest cod: ieirea digit definit ca ntreg cuprins ntre 0 i 9, introducerea variabilei temp i faptul c entitatea are acelai nume cu corpul arhitectural. Nu exist nicio intrare de reset, aa c valoarea iniial a variabilei temp ar putea fi mai mare de 10. n acest caz numrtorul parcurge strile superioare prin incrementare, iar dup starea 15 sau "1111" va intra n ciclul normal de numrare, de la 0 la 9. Eliminarea strilor suplimentare se poate face din start (prin nlocuirea lui temp=10 cu temp=>10), dar implementarea fizic a circuitului va folosi mai multe pori logice din structur. Pe de alt parte, comparaia variabilei temp cu o constant este mai avantajoas dect comparaia cu o alt variabil. Nu mai este necesar sinteza unui comparator complet de 4 bii i se face o economie a resurselor hardware disponibile n circuit.
Pentru sinteza VHDL a unui automat cu stri finite, putem separa structura n dou blocuri funcionale, logica combinaional i logica secvenial, aa cum se poate vedea n figura 3.4. 4 Logica combinationala Logica secventiala intrare iesire stare_prezenta stare_viitoare clock reset
Fig. 3.4 Separarea funcional a unui automat finit
x y Automat finit clock reset S 0 y = 0 S 3 y = 1 S 1 y = 0 S 2 y = 0 reset 0 0 0 0 1 1 1 1
Fig. 3.5 Exemplu de automat finit
Cele dou blocuri ale circuitului pot fi descrise separat prin dou procese diferite. S exemplificm acest lucru pe automatul foarte simplu din figura 3.5. Circuitul are o intrare de date, notat cu x, i o ieire, notat cu y. Aa cum se vede din diagrama strilor, sistemul bucleaz n starea curent dac x = 0 i trece n starea urmtoare dac x = 1. Ieirea capt valoarea logic 1 numai n starea S3, iar intrarea asincron de reset foreaz trecerea sistemului n starea S0:
LIBRARY ieee ; USE ieee.std_logic_1164.all; --------------------------------------------------- ENTITY fsm IS PORT( clock, reset: IN BIT; x: IN BIT; y: OUT BIT); END fsm; --------------------------------------------------- ARCHITECTURE fsm OF fsm IS TYPE stare IS (S0, S1, S2, S3); SIGNAL stare_prezenta, stare_viitoare: stare; BEGIN ---------------------------------------------- PROCESS (clock, reset) BEGIN IF (reset = '1') THEN stare_prezenta <= S0; ELSIF (clock'EVENT AND clock = '1') THEN stare_prezenta <= stare_viitoare; END IF; END PROCESS; ----------------------------------------------
5 PROCESS (stare_prezenta, x) BEGIN CASE stare_prezenta IS WHEN S0 => y <= '0'; IF x = '0' THEN stare_viitoare <= S0; ELSE stare_viitoare <= S1; END IF; WHEN S1 => y <= '0'; IF x = '0' THEN stare_viitoare <= S1; ELSE stare_viitoare <= S2; END IF; WHEN S2 => y <= '0'; IF x = '0' THEN stare_viitoare <= S2; ELSE stare_viitoare <= S3; END IF; WHEN S3 => y <= '1'; IF x = '0' THEN stare_viitoare <= S3; ELSE stare_viitoare <= S0; END IF; END CASE; END PROCESS; END fsm;
Semnalele de intrare-ieire au fost declarate de tip BIT. Chiar dac acest tip de date este mai abstract dect tipul standard logic (STD_LOGIC) folosit pn acum (nu conine starea de nalt impedan sau de don't care), el permite simplificarea scrierii ciclurilor IF, evitnd instruciunea ELSIF. Declaraia de tip (TYPE) permite introducerea unor noi tipuri de date ntr-un model VHDL. Ea numete un tip, n cazul nostru stare, i specific valorile care pot fi folosite pentru un obiect din acel tip (vezi instruciunea TYPE stare IS (S0, S1, S2, S3);). O alt noutate este instruciunea secvenial CASE, introdus deoarece comportarea automatului depinde de diferite valori ale strii prezente. Corpul instruciunii const dintr-o serie de alternative, fiecare ncepnd cu cuvntul cheie WHEN, urmat de una sau mai multe variante i o secven de instruciuni.
4. Modul de lucru
4.1. Se implementeaz circuitul din figura 3.1 folosind mediul ISE i limbajul VHDL. Se face un proiect care conine un fiier .vhd ce descrie comportamental circuitul i se simuleaz funcionarea circuitului n ModelSim.
6 4.2. Se face sinteza VHDL a bistabilului de tip D prezentat n figura 3.2 i se verific funcionarea circuitului folosind cele dou simulatoare: cel existent n mediul ISE i simulatorul ModelSim.
4.3. Se face sinteza VHDL a numrtorului sincron BCD prezentat n figura 3.3 i se verific funcionarea circuitului folosind cele dou simulatoare: cel existent n mediul ISE i simulatorul ModelSim.
4.4. Se face sinteza VHDL a automatului finit prezentat n figura 3.5 i se verific funcionarea circuitului folosind cele dou simulatoare: cel existent n mediul ISE i simulatorul ModelSim.
4.5. S se implementeze n VHDL un bistabil JK cu basculare pe front cresctor de ceas, avnd un semnal asincron de reset, activ pe 1 logic, i dou ieiri complementare, Q i non_Q. Codul VHDL ar putea fi urmtorul:
LIBRARY ieee; USE ieee.std_logic_1164.all; --------------------------------------------------- ENTITY jk_flipflop IS PORT (clock, J, K, reset: IN STD_LOGIC; Q, non_Q: OUT STD_LOGIC); END jk_flipflop; --------------------------------------------------- ARCHITECTURE behv OF jk_flipflop IS -- definim doua semnale suplimentare: SIGNAL stare: STD_LOGIC; SIGNAL intrare: STD_LOGIC_VECTOR (1 DOWNTO 0); BEGIN -- combinam intrarile J si K intr-un singur vector intrare <= J & K; PROCESS (clock, reset) BEGIN IF (reset = '1') THEN stare <= '0'; ELSIF (rising_edge(clock)) THEN CASE (intrare) IS WHEN "11" => stare <= not stare; WHEN "10" => stare <= '1'; WHEN "01" => stare <= '0'; WHEN OTHERS => null; END CASE; END IF; END PROCESS; Q <= stare; non_Q <= not stare; END behv;
4.6. S se fac sinteza VHDL a unui numrtor zecimal de 2 cifre BCD, care numr cresctor de la 00 la 99. Fiecare cifr BCD este decodificat pentru a fi vizualizat pe un afiaj cu 7 segmente. n afar de semnalul de ceas, . 7
reset Numarator clk input: "xabcdefg" b a c d e f g b
Fig. 4.1 Numrtor de 2 cifre BCD cu ieiri pe 7 segmente
sistemul mai are o intrare de reset, care reseteaz numrtorul atunci cnd este activat pe 1 logic. Schema bloc a sistemului i corespondena dintre biii de la ieire i cele 7 segmente ale afiajului sunt reprezentate n figura 4.1. Codul VHDL ar putea fi urmtorul:
LIBRARY ieee; USE ieee.std_logic_1164.all; --------------------------------------------------- ENTITY counter IS PORT (clk, reset: IN STD_LOGIC; digit1, digit2: OUT STD_LOGIC_VECTOR (6 DOWNTO 0)); END counter; --------------------------------------------------- ARCHITECTURE counter OF counter IS BEGIN PROCESS (clk, reset) VARIABLE temp1: INTEGER RANGE 0 TO 10; VARIABLE temp2: INTEGER RANGE 0 TO 10; BEGIN IF (reset = '1') THEN temp1 := 0; temp2 := 0; ELSIF (clk'EVENT AND clk = '1') THEN temp1 := temp1 + 1; IF (temp1 = 10) THEN temp1 := 0; temp2 := temp2 + 1; IF (temp2 = 10) THEN temp2 := 0; END IF; END IF; END IF; CASE temp1 IS WHEN 0 => digit1 <= "1111110"; --7E WHEN 1 => digit1 <= "0110000"; --30 WHEN 2 => digit1 <= "1101101"; --6D WHEN 3 => digit1 <= "1111001"; --79 WHEN 4 => digit1 <= "0110011"; --33 WHEN 5 => digit1 <= "1011011"; --5B WHEN 6 => digit1 <= "1011111"; --5F WHEN 7 => digit1 <= "1110000"; --70 WHEN 8 => digit1 <= "1111111"; --7F WHEN 9 => digit1 <= "1111011"; --7B WHEN OTHERS => NULL; END CASE; CASE temp2 IS WHEN 0 => digit2 <= "1111110"; --7E 8 WHEN 1 => digit2 <= "0110000"; --30 WHEN 2 => digit2 <= "1101101"; --6D WHEN 3 => digit2 <= "1111001"; --79 WHEN 4 => digit2 <= "0110011"; --33 WHEN 5 => digit2 <= "1011011"; --5B WHEN 6 => digit2 <= "1011111"; --5F WHEN 7 => digit2 <= "1110000"; --70 WHEN 8 => digit2 <= "1111111"; --7F WHEN 9 => digit2 <= "1111011"; --7B WHEN OTHERS => NULL; END CASE; END PROCESS; END counter;
Se observ repetarea de dou ori a codului pentru decodificarea BCD 7 segmente. Acest lucru se poate evita prin definirea unei proceduri n corpul arhitectural (folosind cuvntul cheie PROCEDURE) i apelarea ei ulterioar, dar deocamdat nu ne ocupm de acest aspect al limbajului VHDL.