Vhdl

  • December 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Vhdl as PDF for free.

More details

  • Words: 4,199
  • Pages: 28
Università degli Studi di Ferrara DIPARTIMENTO DI INGEGNERIA Corso di “Linguaggi di descrizione dell’Hardware”

Relazione di laboratorio Studenti: Mirko Buzzoni e Elisa Benetti

Sommario 1. INTERFACCIA DI COMANDI DEL SIMULATORE - ASSEGNAMENTO AI SEGNALI - TIPI DI RITARDO........................... ERROR! BOOKMARK NOT DEFINED. 2. VHDL STRUTTURALE ....................................................................................... 5 2.1 2.2 2.3

AND, OR ,NOT E EXOR ............................. 5 COSTRUZIONE E TEST DI UN FULL-ADDER ............................................................ 6 COSTRUZIONE E TEST DI UN 4 BIT ADDER ........................................................... 8 REALIZZAZIONE DI UNA LIBRERIA CON

3. COSTRUZIONE E TEST DI UN FLIP FLOP TIPO D ........................................... 11 4. COSTRUZIONE E TEST DI UN COMPARATORE A 4 BIT ................................... 14 5. DATAPATH .................................................................................................... 16 6. RAM .............................................................................................................. 22 7. ALU............................................................................................................... 25

1

1.0 Interfaccia di comandi del simulatore - assegnamento ai segnali tipi di ritardo Obiettivo di questa esercitazione è familiarizzare con l’ ambiente di sviluppo, a tal scopo abbiamo definito un semplice Testbench senza segnali di ingresso o uscita, al quale abbiamo associato tre segnali, a, b e c che variano nel tempo,in particolare: • a si porta a zero dopo 5 ns e a uno dopo 11 ns; • b si porta a uno dopo 7 ns, a zero dopo 8 ns, a 1 dopo 13 ns, a zero dopo 24 ns e infine torna a 1 dopo 30 ns • c si porta a zero dopo 13 ns e resta stabile L’ esecuzione della simulazione è ciclica (wait) poichè i segnali si ripetono uguali con un offset di 30 ns.

Visione generale di tutti i segnali coinvolti:

2

Abbiamo quindi analizzato i vari tipi di ritardo: • RITARDO DI TRASPORTO studiato sul segnale a e settato a 18 ns. Il segnale trans assumerà il valore negato di a con un ritardo di 18 ns, come è verificato nella seguente figura:



RITARDO INERZIALE studiato sul segnale b e settato a 10 ns. Il segnale inerz1 assumerà il valore negato di b con un ritardo di 10 ns, come si vede nella seguente figura.

3

Si noti come la prima e la seconda variazione di b, non vengono rilevate nel segnale inerz1, in quanto la loro durata è minore dei 10 ns da noi settati nel ritardo. •

RITARDO INERZIALE CON REJECT studiato sul segnale b e settato a 10 ns. Il reject posto a 4 ns, impone che l’ invertitore sopprima gli impulsi di durata minore rispetto a quella specificata. Il segnale inerz2 assumerà il valore negato di b con un ritardo di 10 ns, come si vede nella seguente figura.

Al contrario di inerz1, infatti, inerz2 mostra anche la seconda variazione di b. La prima, essendo di durata 1 ns, quindi minore dei 4 ns, viene soppressa, la seconda invece no, essendo essa di durata 5ns.

4

2.0 VHDL strutturale - realizzazione di una libreria con AND, OR ,NOT e EXOR costruzione e test di un full-adder - costruzione e test di un 4 bit adder 2.1

X 0 0 1 1

In accordo con la forte analogia del vhdl con il paradigma oop, abbiamo perseguito i nostri obiettivi riusando codice e per mezzo di una descrizione bottom-up che ci consente di gestire la crescente complessità. Per prima cosa realizziamo la nostra libreria in vhdl con i componenti necessari, si noti che la descrizione è behavioural per rispettare la minima granularità nella rappresentazione che è appunto il gate logico:

Y 0 1 0 1

AND 0 0 0 1

OR 0 1 1 1

EXOR 1 0 0 1

Listato vhdl:

END arcor2;

-------AND---------library ieee; use ieee.std_logic_1164.all; ENTITY and2 is generic (trise : time := 4 ns); port(x, y : in std_logic; z : out std_logic); END and2;

----------NOT---------------library ieee; use ieee.std_logic_1164.all; ENTITY not2 is generic(trise : time := 4 ns); port(x : in std_logic; z: out std_logic); END not2; ARCHITECTURE arcnot2 of not2 is begin z <= not x after trise; END arcnot2; --------XOR--------------------library ieee; use ieee.std_logic_1164.all; ENTITY xor2 is generic(trise : time := 4 ns); port(x, y : in std_logic; z : out std_logic); END xor2; ARCHITECTURE arcxor2 of xor2 is begin z <= x xor y after trise; END arcxor2;

ARCHITECTURE arcand2 of and2 is begin z <= x and y after trise; END arcand2; -------OR-----------------library ieee; use ieee.std_logic_1164.all; ENTITY or2 is generic(trise : time := 4 ns); port(x, y : in std_logic; z : out std_logic); END or2; ARCHITECTURE arcor2 of or2 is begin z <= x or y after trise;

5

2.2

A questo punto è aumentato il livello di descrizione: grazie ai componenti appena definiti possimo relizzare il full-adder e testarlo mediante un opportuno testbench. In accordo con quanto asserito precedentemente,la descrizione del full-adder questa volta è di tipo comportamentale.

Cin 0 0 0 0 1 1 1 1

A 0 0 1 1 0 0 1 1

B 0 1 0 1 0 1 0 1

Sum 0 1 1 0 1 0 0 1

Cout 0 0 0 1 0 1 1 1

-----------FULL ADDER-----------------------library ieee; use ieee.std_logic_1164.all; ENTITY full_Adder is port(a, b ,cin : in std_logic; sum,cout : out std_logic); END full_Adder; ARCHITECTURE arcfa of full_Adder is signal d,e,f : std_logic; component and2 is port(x, y : in std_logic; z : out std_logic); end component; for all : and2 use entity work.and2(arcand2); component or2 is port(x, y : in std_logic; z : out std_logic); end component or2; for all : or2 use entity work.or2(arcor2); component xor2 is port(x, y : in std_logic; z : out std_logic); end component xor2; for all : xor2 use entity work.xor2(arcxor2); 6

begin a1 : and2 port map (x =>a, y =>b, z=>e); x1 : xor2 port map (x =>a, y =>b, z=>d); a2 : and2 port map (x =>cin, y=>d, z=>f); x2 : xor2 port map (x =>cin, y =>d, z=>sum); o1 : or2 port map (x =>f, y =>e, z=>cout); END arcfa; -----------TESTBENCH FULL ADDER------------------------library ieee; use ieee.std_logic_1164.all; ENTITY fa_tb is END fa_tb; ARCHITECTURE arctb of fa_tb is signal a1, b1, c1 : std_logic; signal s,c2 : std_logic; component fullAdder is port(a,b,cin : in std_logic; sum,cout : out std_logic); end component; for all : fullAdder use entity work.full_Adder(arcfa); begin add : fullAdder port map (a=>a1,b=>b1,cin=>c1,sum=>s,cout=>c2); c1 <= '0' after 15 ns; a1 <= '0' after 10 ns, '1' after 35 ns; b1 <= '1' after 10 ns, '0' after 35 ns; END arctb;

Il risultato della simulazione è il seguente:

7

2.3

Infine, costruiamo un 4 bit – adder, a partire dal full-adder come componente, e il relativo testbench per stimolarlo: a0 a1 a2 a3 b0 b1 b2 b3

0 1 0 1 1 0 1 1

s0 s1 s2 s3 cin cout

1 1 1 0 0 1

Particolare configurazione di ingresso del 4-bit adder da noi imposta

-----------4bit ADDER-----------------------library ieee; use ieee.std_logic_1164.all; ENTITY bit_Adder is port(a0, b0 ,a1, b1 ,a2, b2 ,a3, b3 ,cin : in std_logic; s0, s1, s2, s3, carryout : out std_logic); END bit_Adder; ARCHITECTURE arc4bit of bit_Adder is signal c1,c2,c3 : std_logic; component full_Adder is port(a, b ,cin : in std_logic; sum,cout : out std_logic); end component; for all : full_Adder use entity work.full_Adder(arcfa); begin fa1 : full_Adder port map (a =>a0, b =>b0, cin=>cin, sum=>s0 ,cout=>c1); fa2 : full_Adder port map (a =>a1, b =>b1, cin=>c1, sum=>s1 ,cout=>c2); fa3 : full_Adder port map (a =>a2, b =>b2, cin=>c2, sum=>s2 ,cout=>c3); fa4 : full_Adder port map (a =>a3, b =>b3, cin=>c3, sum=>s3 ,cout=>carryout); END arc4bit; -----------TESTBENCH 4BIT ADDER------------------------library ieee; use ieee.std_logic_1164.all; ENTITY ba_tb is END ba_tb; ARCHITECTURE arctb4ba of ba_tb is signal in10, in11, in12, in13, in20,in21,in22,in23,cin0 : std_logic; 8

signal out0,out1, out2,out3,cout0 : std_logic; component bit_Adder is port(a0, b0 ,a1, b1 ,a2, b2 ,a3, b3 ,cin : in std_logic; s0, s1, s2, s3, carryout : out std_logic); end component; for all : bit_Adder use entity work.bit_Adder(arc4bit); begin fb : bit_Adder port map (a0=>in10, a1=>in11, a2=>in12, a3=>in13, b0=>in20, b1=>in21, b2=>in22, b3=>in23, cin=>cin0, s0=>out0, s1=>out1, s2=>out2, s3=>out3, carryout=>cout0); in10 <= '0' after 15 ns; in11 <= '1' after 15 ns; in12 <= '0' after 15 ns; in13 <= '1' after 15 ns; in20 <= '1' after 15 ns; in21 <= '0' after 15 ns; in22 <= '1' after 15 ns; in23 <= '1' after 15 ns; cin0 <= '0' after 15 ns; END arctb4ba;

Simulazione degli ingressi:

9

......e simulazione delle uscite del 4-bit adder e dei singoli full-adder:

Si noti che il carry out cout0 commuta immediatamante senza ritardo rispetto all’uscita out3: il quarto full-adder in questa configurazione d’ingresso riceve due segnali alti, dunque il carry commuta immediatamente anche se non è intercorso il ritardo di propagazione del carry che lega le operazioni dei singoli full-adder.

10

3.0 Costruzione e test di un flip flop tipo D

Schema di principio del Latch D (l’ enable è il clock nel nostro caso)

Schema di interfaccia (con le specifiche del progetto)

Codice vhdl:descrizione behavioural del flip flop D, con le features aggiuntive dell’enable e reset sincroni library ieee; use ieee.std_logic_1164.all; entity dff is generic(tprop : time := 8 ns; tsu : time := 2 ns); port(d :in std_logic; clk : in std_logic; enable : in std_logic; reset : in std_logic; q : out std_logic; qn : out std_logic); end dff; architecture behav of dff is begin one : process (clk) begin if((clk = '1' and clk'last_value = '0') and enable = '1') then if(d'stable(tsu) and (reset='0' or reset = 'U')) then if(d='0')then q <= '0' after tprop; qn <= '1' after tprop; elsif (d = '1')then q <= '1' after tprop; qn <= '0' after tprop; else q <= 'X'; qn <= 'X'; end if; elsif((reset'stable(tsu))and(reset='1'))then q <= '0' after tprop; qn <= '1' after tprop; else q <= 'X'; qn <= 'X'; end if; end if; end process one; end behav; 11

library ieee; use ieee.std_logic_1164.all; ENTITY dff_tb is END dff_tb; ARCHITECTURE arcdfftb of dff_tb is signal d0, clk0, enable0,reset0 : std_logic; signal q0,qn0 : std_logic; component dff is port(d,clk,enable,reset : in std_logic; q,qn : out std_logic); end component; for all : dff use entity work.dff(behav); begin flipflop : dff port map (d=>d0,clk=>clk0,enable=>enable0,reset=>reset0,q=>q0,qn=>qn0); d0 <= '1','0' after 29 ns,'1' after 30 ns; clk0 <= '0' after 5 ns, '1' after 10 ns, '0' after 15 ns, '1' after 20 ns, '0' after 25 ns, '1' after 30 ns, '0' after 35 ns, '1' after 40 ns, '0' after 45 ns, '1' after 50 ns, '0' after 55 ns; enable0 <= '1'; reset0 <= '1' after 37 ns; END arcdfftb; Screenshot della simulazione:

caso particolare con d0 che viola il tempo di setup e reset sincrono che occorre a 37ns

12

Imponendo invece la seguente variazione del segnale di ingresso d0, otteniamo: d0 <= '0','1' after 7 ns,'0' after 12 ns;

“Tradizionale” funzionamento del ff-D In base alle specifiche di funzionamento del flipflop di tipo D si ha il latch del segnale “d0” solo al raise del clock e solo se nello stesso istante il reset è basso. Il segnale in ingresso è latchato con ritardo di propagazione tprop.

13

4.0 Costruzione e test di un comparatore a 4 bit Continuiamo la nostra conduttura realizzando il comparatore a 4 bit. Al solito il comparatore prende in ingresso due parole, da 4 bit nel nostro caso, e restituisce 1 se la prima è strettamente maggiore della seconda, 0 altrimenti. Per realizzare il componente ci siamo serviti del modello comportamentale: operativamente viene confrontata ogni coppia di bit, a partire da quella di peso minore; poichè facciamo la valutazione in questa direzione, si rende necessario un flag(interno) per tenere traccia dell’ultimo confronto effettuato. Il flag inizialmente è settato a 0, quindi ad ogni iterazione, se il bit della prima parola è maggiore di quello della seconda allora il flag viene settato a 1, se è minore il flag viene settato a zero, se uguale viene mantenuto il flag risultante dal confronto precedente; il caso indeterminato non viene contemplato.

Schema del comparatore -----------COMPARATORE 4 BIT-----------------------library ieee; use ieee.std_logic_1164.all; ENTITY comp4 is generic(tprop: time := 5 ns); port(a,b: in std_logic_vector(0 to 3); o: out std_logic); END comp4; ARCHITECTURE arccomp4 of comp4 is begin one:process(a,b) variable i : std_logic; variable flag : std_logic; begin flag :='0'; for i in 0 to 3 loop if (a(i) > b(i)) then flag := '1'; elsif(a(i) < b(i)) then flag := '0'; 14

end if; end loop; if (flag = '1') then o <= '1'; else o <= '0'; end if; end process one; END arccomp4; -----------TESTBENCH COMPARATORE 4 BIT------------------------library ieee; use ieee.std_logic_1164.all; ENTITY comp4_tb is END comp4_tb; ARCHITECTURE arctbcomp4 of comp4_tb is signal in1,in2: std_logic_vector(0 to 3); signal out0: std_logic; component comp4 is port(a,b : in std_logic_vector(0 to 3); o : out std_logic); end component; for all : comp4 use entity work.comp4(arccomp4); begin c4 : comp4 port map (a=>in1, b=>in2, o=>out0); in1 <= "0010" after 5 ns, "1101" after 10 ns, "0000" after 15 ns, "1010" after 20 ns,"0011" after 25 ns; in2 <= "1001" after 5 ns, "1010" after 10 ns, "0000" after 15 ns, "1001" after 20 ns,"1110" after 25 ns; END arctbcomp4;

Simulazione di ingressi e uscita del comparatore 15

5.0 Datapath Per la realizzazione di questo datapath necessitiamo di un ultimo componente: un 4 bit register. Quest’ultimo è composto da 4 flip flop D opportunamente interconnessi:

Codice VHDL della descrizione strutturale di un 4 bit register: library ieee; use ieee.std_logic_1164.all; ENTITY register4 is port(a: in std_logic_vector(0 to 3); dv,r,ck: in std_logic; b: out std_logic_vector(0 to 3)); END register4; ARCHITECTURE arcre of register4 is component dff is port(d, clk, enable, reset : in std_logic; q, qn : out std_logic); end component; for all : dff use entity work.dff(behav); begin ff1 : dff port map (d => a(0), clk => ck, enable=> dv, reset=> r , q=> b(0)); ff2 : dff port map (d => a(1), clk => ck, enable=> dv, reset=> r , q=> b(1)); ff3: dff port map (d => a(2), clk => ck, enable=> dv, reset=> r , q=> b(2)); ff4: dff port map (d => a(3), clk => ck, enable=> dv, reset=> r, q=> b(3)); END arcre;

16

Scopo di questo componente è sincronizzare gli ingressi sfasati di ritardi diversi, come si evince dal seguente screenshot:

Simulazione del funzionamento di un register

17

Avendo ora a disposizione tutti i componenti necessari, possiamo finalmente realizzare il nostro datapath. Lo schema logico è riportato di seguito:

Codice VHDL strutturale corrispondente: library ieee; use ieee.std_logic_1164.all; ENTITY datapath is port(a: in std_logic_vector(0 to 3); uscita: out std_logic_vector(0 to 3); dv,reset,ck: in std_logic); END datapath; ARCHITECTURE arcdat of datapath is signal outr1,outr2,outadder : std_logic_vector(0 to 3); signal outcomp : std_logic; component register4 is port(a: in std_logic_vector(0 to 3); dv,r,ck: in std_logic; b: out std_logic_vector(0 to 3)); 18

end component; for all : register4 use entity work.register4(arcre); component bit_Adder is port(a0, b0 ,a1, b1 ,a2, b2 ,a3, b3 ,cin : in std_logic; s0, s1, s2, s3, carryout : out std_logic); end component; for all : bit_Adder use entity work.bit_Adder(arc4bit); component comp4 is port(a,b: in std_logic_vector(0 to 3); o: out std_logic); end component; for all : comp4 use entity work.comp4(arccomp4); begin r1 : register4 port map (a => a, dv => dv, ck=> ck, b=>outr1,r=>'0'); comp1 : comp4 port map (a => outr1, b => outr2, o=> outcomp); add1 : bit_Adder port map (a0 => outr1(0),a1 => outr1(1),a2 => outr1(2),a3 => outr1(3),b0 => outr2(0),b1 => outr2(1),b2 => outr2(2),b3 => outr2(3),cin => '0', s0 => outadder(0), s1=> outadder(1), s2=> outadder(2) , s3=> outadder(3)); r2 : register4 port map (a => outadder, dv => outcomp, ck=>ck, b=>outr2,r=>reset); uscita <= outr2; END arcdat; -----------------------------------TESTBENCH DATAPATH------------------------------------------------library ieee; use ieee.std_logic_1164.all; ENTITY dptb is END dptb; ARCHITECTURE arcdptb of dptb is signal in1: std_logic_vector(0 to 3); signal uscita1: std_logic_vector(0 to 3); signal ck1,dv1,reset1: std_logic; component datapath is port(a: in std_logic_vector(0 to 3);dv,reset,ck: in std_logic;uscita: out std_logic_vector(0 to 3)); end component; for all : datapath use entity work.datapath(arcdat); begin data1: datapath port map (a=>in1,dv=>dv1,ck=>ck1,reset=>reset1,uscita=>uscita1); in1 <= "1011" after 7 ns, "1111" after 106 ns; dv1 <= '1' after 4 ns; reset1 <= '1' after 5 ns, '0' after 56 ns; ck1 <= '0' after 5 ns, '1' after 10 ns, '0' after 15 ns, '1' after 20 ns, '0' after 25 ns, '1' after 30 ns, '0' after 35 ns, '1' after 40 ns, '0' after 45 ns, '1' after 50 ns, '0' after 55 ns, '1' after 60 ns, '0' after 65 ns, '1' after 70 ns, '0' after 75 ns, '1' after 80 ns, '0' after 85 ns, '1' after 90 ns, '0' after 95 ns, '1' after 100 ns, '0' after 105 ns, '1' after 110 ns, '0' after 115 ns; END arcdptb; Nel caso particolare di questo datapath, l’ uscita è retroazionata sugli ingressi del comparatore e dell’ addizionatore, ciò si riflette in un malfunzionamento del componente in quanto inizialmente l’uscita è indeterminata. Per prevenire tale malfunzionamento, poniamo a 1 il segnale di reset: la durata del reset deve essere pari al ritardo di propagazione massimo indotto dal 4 bit adder sulle uscite rispetto ai suoi segnali in ingresso.

19

Simulazione di una parola in ingresso e dell’ uscita dell’ addizionatore

Simulazione delle due parole di ingresso e il bit di uscita del comparatore 20

Simulazione dell’ ingresso del datapath, dell’uscita (corrispondente all’uscita del secondo register) e del segnale di clock

21

6.0 RAM Obiettivo di questa esperienza è realizzare una memoria ram. In particolare essa è composta da un decoder degli indirizzi che prende in ingresso parole da 5 bit e le decodifica in uno dei 25 possibili indirizzi, un bus da 8 bit per lettura e scrittura ( pilotato da rd e wr per dicriminare rispettivamente fra read e write), infine vi è un segnale di clock per rendere sincrone le operazioni. La ram è in grado di contenere dunque 32 parole da 8 bit ciascuna.

Codice vhdl con descrizione di tipo comportamentale: --------------------------RAM-----------------------------------library ieee; use ieee.std_logic_1164.all; entity ram is port(clk: in std_logic; rd: in std_logic; wr: in std_logic; inaddr: in std_logic_vector(4 downto 0); busin: in std_logic_vector(7 downto 0); busout: out std_logic_vector(7 downto 0) ); end ram; architecture arcram of ram is type memorytype is array (31 downto 0) of std_logic_vector (7 downto 0); signal memory: memorytype; begin one : process (clk) variable myint: integer:= 0; variable myint1: integer:= 0; variable i: integer := 0; 22

begin myint := 0; for i in 4 downto 0 loop if (inaddr(i)='1') then myint := myint + (2**i); end if; end loop; if(clk = '1' and clk'last_value = '0') then if((wr='1')and(rd='0')) then memory(myint)<=busin; end if; if((wr='0')and(rd='1')) then busout<=memory(myint); end if; end if; end process one; end arcram; ----------TESTBENCH-------------------------------library ieee; use ieee.std_logic_1164.all; ENTITY ramtb is END ramtb; ARCHITECTURE arcramtb of ramtb is signal busin1: std_logic_vector(7 downto 0); signal busout1: std_logic_vector(7 downto 0); signal inaddr1: std_logic_vector(4 downto 0); signal clk1,wr1,rd1: std_logic; component ram is port(clk: in std_logic; rd: in std_logic; wr: in std_logic; inaddr: in std_logic_vector(4 downto 0); busin: in std_logic_vector(7 downto 0); busout: out std_logic_vector(7 downto 0) ); end component; for all : ram use entity work.ram(arcram); begin ram1: ram port map (inaddr=>inaddr1,busin=>busin1,busout=>busout1,rd=>rd1,wr=>wr1,clk=>clk1); busin1 <= "10111000" after 7 ns, "11110010" after 16 ns; wr1 <= '0','1' after 5 ns, '0' after 11 ns,'1' after 16 ns, '0' after 26 ns; rd1 <= '0','1' after 36 ns, '0' after 46 ns,'1' after 56 ns, '0' after 66 ns; inaddr1 <= "01000" after 7 ns,"10010" after 16 ns,"01000" after 37 ns, "10010" after 57 ns; clk1 <= '1','0' after 5 ns, '1' after 10 ns, '0' after 15 ns, '1' after 20 ns, '0' after 25 ns, '1' after 30 ns, '0' after 35 ns, '1' after 40 ns, '0' after 45 ns, '1' after 50 ns, '0' after 55 ns, '1' after 60 ns, '0' after 65 ns, '1' after 70 ns, '0' after 75 ns, '1' after 80 ns, '0' after 85 ns, '1' after 90 ns, '0' after 95 ns, '1' after 100 ns, '0' after 105 ns, '1' after 110 ns, '0' after 115 ns; END arcramtb;

23

Nello screenshot il busin, busout, bus degli indirizzi, clock e segnali di rd e wr: si possono vedere le due scritture e due letture corrispondenti, agli indirizzi di memoria 8 e 18...

....e il contenuto della memoria stessa.

24

7.0 ALU Il nostro iter si conclude con la realizzazione di una semplice alu che gestisce le seguenti operazioni: and, or, xor, not, somma, sottrazione, shift a destra e shift a sinistra; denotate da una delle 8 possibili configurazioni del bus degli indirizzi, assumendo che il dominio dei valori sia {0,1}, in tutti gli altri casi l’ uscita risulterà indeterminata. La rappresentazione in complemento a 2 o meno delle due parole di ingresso è completamente trasparente nell’ implementazione della alu. Al solito abbiamo un segnale di clock che temporizza le operazioni da svolgere. Il carry out segnala sia la condizione critica di overflow che la presenza di un numero negativo sul busout. Il carry in non è presente come segnale di ingresso, ma è utilizzato internamente al componente per le operazioni di riporto.

Descrizione behavioural della alu: library ieee; use ieee.std_logic_1164.all; entity alu is port(addr: in std_logic_vector(2 downto 0); a: in std_logic_vector(7 downto 0); b: in std_logic_vector(7 downto 0); clk: in std_logic; busout: out std_logic_vector(7 downto 0); cout: out std_logic ); end alu; architecture arcalu of alu is begin one : process (clk, addr) variable avar: std_logic_vector(7 downto 0); variable bvar: std_logic_vector(7 downto 0); variable outvar: std_logic_vector(7 downto 0); variable cin: std_logic; variable coutvar: std_logic; variable aux: std_logic_vector(7 downto 0); begin avar := a; bvar := b; cin :='0'; case addr is when "000" => --and if(clk = '1' and clk'last_value = '0') then 25

for i in 7 downto 0 loop outvar(i) := avar(i) and bvar(i); end loop; busout <= outvar; end if; when "001" => --or if(clk = '1' and clk'last_value = '0') then for i in 7 downto 0 loop outvar(i) := avar(i) or bvar(i); end loop; busout <= outvar; end if; when "010" => --not if(clk = '1' and clk'last_value = '0') then for i in 7 downto 0 loop outvar(i) := not avar(i); end loop; busout <= outvar; end if; when "011" => --somma if(clk = '1' and clk'last_value = '0') then for i in 0 to 7 loop outvar(i) := avar(i) xor bvar(i) xor cin; coutvar := (avar(i) and bvar(i)) or (avar(i) and cin) or (bvar(i) and cin); cin := coutvar; end loop; busout <= outvar; cout <= coutvar; end if; when "100" => --sottrazione if(clk = '1' and clk'last_value = '0') then bvar := not bvar; aux := "00000001"; for i in 0 to 7 loop outvar(i) := aux(i) xor bvar(i) xor cin; coutvar := (aux(i) and bvar(i)) or (aux(i) and cin) or (bvar(i) and cin); cin := coutvar; end loop; bvar := outvar; cin:= '0'; avar := not avar; for i in 0 to 7 loop outvar(i) := aux(i) xor outvar(i) xor cin; coutvar := (aux(i) and outvar(i)) or (aux(i) and cin) or (outvar(i) and cin); cin := coutvar; end loop; busout <= outvar; cout <= coutvar; end if; when "101" => --xor if(clk = '1' and clk'last_value = '0') then for i in 7 downto 0 loop outvar(i) := avar(i) xor bvar(i); end loop; busout <= outvar; 26

end if; when "110" => --lshift if(clk = '1' and clk'last_value = '0') then for i in 6 downto 0 loop outvar(i+1) := avar(i); end loop; outvar(0) := '0'; busout <= outvar; end if; when "111" => --rshift if(clk = '1' and clk'last_value = '0') then for i in 6 downto 0 loop outvar(i) := avar(i+1); end loop; outvar(7) := '0'; busout <= outvar; end if; when others => busout <= "XXXXXXXX"; end case; end process one; end arcalu; ----------TESTBENCH-------------------------------library ieee; use ieee.std_logic_1164.all; ENTITY alutb is END alutb; ARCHITECTURE arcalutb of alutb is signal addr1: std_logic_vector(2 downto 0); signal busout1: std_logic_vector(7 downto 0); signal a1: std_logic_vector(7 downto 0); signal b1: std_logic_vector(7 downto 0); signal clk1: std_logic; signal cout1: std_logic; component alu is port(addr: in std_logic_vector(2 downto 0); a: in std_logic_vector(7 downto 0); b: in std_logic_vector(7 downto 0); clk: in std_logic; busout: out std_logic_vector(7 downto 0); cout: out std_logic ); end component; for all : alu use entity work.alu(arcalu); begin alu1: alu port map (addr=>addr1,a=>a1,busout=>busout1,b=>b1,clk=>clk1,cout=>cout1); clk1 <= '1','0' after 5 ns, '1' after 10 ns, '0' after 15 ns, '1' after 20 ns, '0' after 25 ns, '1' after 30 ns, '0' after 35 ns, '1' after 40 ns, '0' after 45 ns, '1' after 50 ns, '0' after 55 ns, '1' after 60 ns, '0' after 65 ns, '1' after 70 ns, '0' after 75 ns, '1' after 80 ns, '0' after 85 ns, '1' after 90 ns, '0' after 95 ns, '1' after 100 ns, '0' after 105 ns, '1' after 110 ns, '0' after 115 ns; a1 <= "10100000" after 5 ns,"11111100" after 16 ns, "01101001" after 26 ns, "10011010" after 36 ns, "10101010" after 46 ns, "01101011" after 56 ns, "10111011" after 66 ns, "11111111" after 76 ns; b1 <= "01011100" after 5 ns,"10010100" after 16 ns, "10011000" after 56 ns, "10000001" after 66 ns, "10000001" after 76 ns; 27

addr1 <= "001" after 5 ns,"000" after 16 ns, "110" after 26 ns, "111" after 36 ns,"010" after 46 ns, "101" after 56 ns,"011" after 66 ns,"100" after 76 ns,"XXX" after 90 ns; END arcalutb;

In questo screenshot è riportato un esempio per ogni operazione possibile

28

Related Documents

Vhdl
November 2019 32
Vhdl
December 2019 25
Vhdl
May 2020 12
Vhdl
November 2019 22
Vhdl Chapter6
April 2020 4
Vhdl Programs
October 2019 16