DMI – Corso di laurea magistrale in Informatica
Copyleft
2018 Giuseppe Scollo
in questa esercitazione si trattano descrizioni in VHDL di componenti hardware di frequente impiego:
vari aspetti e costrutti del linguaggio VHDL vengono introdotti nel contesto degli esempi proposti
inoltre si propone un'esperienza di laboratorio in cui confluiscono diversi aspetti di VHDL illustrati dagli esempi qui presentati e alcuni componenti possono essere riusati per la realizzazione dell'esperimento proposto
il tipo standard BIT, a due valori booleani, non è sufficiente a rappresentare tutte le situazioni che possono presentarsi nella progettazione di circuiti
le porte tri-state hanno questo impiego tipico
porta tri-state
lo standard IEEE 1164 definisce il tipo std_ulogic a nove valori:
ma std_ulogic non ammette l'accesso di più driver su una stessa linea
risoluzione della contesa fra valori del tipo std_logic
library ieee;
use ieee.std_logic_1164.all;
entity tri_state is
port (x, en : in std_logic;
y : out std_logic);
end entity tri_state;
architecture when_else of tri_state is
begin
y <= x when en = '1' else 'Z';
end architecture when_else;
unità funzionale utile per diversi impieghi, per esempio:
specifica VHDL del decodificatore 2→4
library ieee;
use ieee.std_logic_1164.all;
entity decoder2 is
port (
a : in std_logic_vector(1 downto 0);
z : out std_logic_vector(3 downto 0)
);
end entity decoder2;
architecture when_else of decoder2 is
begin
z <= "0001" when a = "00" else
"0010" when a = "01" else
"0100" when a = "10" else
"1000" when a = "11" else
"XXXX";
end architecture when_else;
specifica VHDL generica del decodificatore (Zwolinski, sez. 4.2.3):
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity decoder is
generic (n : POSITIVE);
port (
a : in std_logic_vector(n-1 downto 0);
z : out std_logic_vector(2**n-1 downto 0)
);
end entity decoder;
architecture rotate of decoder is
constant z_out : BIT_VECTOR(2**n-1 downto 0) :=
(0 => '1', others => '0');
begin
z <= to_StdLogicVector (z_out sll
to_integer(unsigned(a)));
end architecture rotate;
operatori di scorrimento VHDL
dispositivo familiare di uso quotidiano ...
l'esempio che segue (tratto da Zwolinski, sez. 4.2.3)
Zwolinski, Figure 4.3 - Seven-segment display
library ieee;
use ieee.std_logic_1164.all;
entity seven_seg is
port (a : in std_logic_vector(3 downto 0);
 
z : out std_logic_vector(6 downto 0));
end entity seven_seg;
architecture with_select of seven_seg is
begin
with a select
z <= "1110111" when "0000",
"0010010" when "0001",
"1011101" when "0010",
"1011011" when "0011",
"0111010" when "0100",
"1101011" when "0101",
"1101111" when "0110",
"1010010" when "0111",
"1111111" when "1000",
"1111011" when "1001",
"1101101" when
"1010"|"1011"|"1100"|"1101"|"1110"|"1111",
"0000000" when others;
end architecture with_select;
specifica VHDL di un multiplatore a singolo input di selezione:
library ieee;
use ieee.std_logic_1164.all;
entity mux1 is
port (
s : in std_logic;
a : in std_logic;
b : in std_logic;
y : out std_logic
);
end entity mux1;
architecture basic of mux1 is
begin
y <= a when s = ’0’ else
b when s = ’1’ else
’X’;
end architecture basic;
multiplatore a due input di selezione
come generalizzare a n ingressi di selezione?
specifica di una porta OR a n ingressi:
library ieee;
use ieee.std_logic_1164.all;
entity wide_or is
generic (n : POSITIVE);
port (
x : in std_logic_vector(n-1 downto 0);
y : out std_logic);
end entity wide_or;
architecture sequential of wide_or is
begin
process (x) is
variable z : std_logic;
begin
z := x(0);
if n > 1 then
for i in 1 to n-1 loop
z := x(i) or z;
end loop;
end if;
y <= z;
end process;
end architecture sequential;
multiplatore a n ingressi di selezione
library ieee;
use ieee.std_logic_1164.all;
entity mux is
generic (n : POSITIVE := 1);
port (
s : in std_logic_vector(n-1 downto 0);
a : in std_logic_vector(2**n-1 downto 0);
z : out std_logic);
end entity mux;
architecture structural of mux is
signal decout : std_logic_vector(2**n-1 downto 0);
signal andout : std_logic_vector(2**n-1 downto 0);
begin
di: entity WORK.decoder generic map (n)
port map (a => s, z => decout);
oi: entity WORK.wide_or generic map (2**n)
port map (x => andout, y => z);
andout <= a and decout;
end architecture structural;
istanziazione del multiplatore generico
library ieee;
use ieee.std_logic_1164.all;
entity mux2 is
port (
s : in std_logic_vector(1 downto 0);
a : in std_logic_vector(3 downto 0);
z : out std_logic);
end entity mux2;
architecture instance of mux2 is
begin
di: entity WORK.mux generic map (2)
port map (s, a, z);
end architecture instance;
una ALU è una unità multifunzione: un input di controllo seleziona l'operazione da eseguire
S | funzione |
00 | Q <= A or B |
01 | Q <= A and B |
10 | Q <= not B |
11 | Q <= A xor B |
library ieee;
use ieee.std_logic_1164.all;
entity alu_logic is
generic ( n : POSITIVE := 16 );
port (
a : in std_logic_vector((n−1) downto 0);
b : in std_logic_vector((n−1) downto 0);
s : in std_logic_vector(1 downto 0);
q : out std_logic_vector((n−1) downto 0)
);
end entity alu_logic;
architecture with_select of alu_logic is
constant undefined : std_logic_vector(n-1 downto 0) :=
(others => 'X');
begin
with s select
q <= a or b when “00”,
a and b when “01”,
not b; when “10”,
a xor b when “11”,
undefined when others;
end architecture with_select;
full-adder da 1 bit
per operandi di più bit, la funzione aritmetica dell'ALU può specificarsi in stile strutturale o funzionale; quest'ultimo come segue
library ieee;
use IEEE.std_logic_1164.all;
entity adder is
generic(n : POSITIVE := 16);
port (
a : in std_logic_vector (n-1 downto 0);
b : in std_logic_vector (n-1 downto 0);
ci : in std_logic;
sum : out std_logic_vector (n-1 downto 0);
co : out std_logic
);
end entity adder;
architecture sequential of adder is
begin
process(a,b,ci)
variable carry : std_logic;
variable psum : std_logic_vector(n-1 downto 0);
begin
carry := ci;
for i in 0 to n-1 loop
psum(i) := a(i) xor b(i) xor carry;
carry :=
(a(i) and b(i)) or (((a(i) xor b(i)) and carry);
end loop;
sum <= psum;
co <= carry;
end process;
end architecture sequential;
il simulatore di ALU a 8 bit realizzato da S. Lentini e G. Nicotra illustra come si possa costruire iterativamente l'ALU a 8 bit componendo opportunamente stadi di ALU a 1 bit
usando i costrutti VHDL visti negli esempi di questa esercitazione:
schematico di ALU a 1 bit (Figura 3-19 in (Tanenbaum, 2006))
letture raccomandate:
materiali utili per l'esperienza di laboratorio proposta
(fonti: Biblioteca DMI, Altera University Program, 2016)
sorgenti VHDL: