Mudanças entre as edições de "ELD129002-Engtelecom (Diário) - Prof. Marcos Moecke"
Linha 1 188: | Linha 1 188: | ||
{{collapse bottom}} | {{collapse bottom}} | ||
− | ===Unidade | + | ===Unidade 4 - Introdução a linguagem VHDL e Quartus/ModelSim=== |
* 6 ENCONTROS | * 6 ENCONTROS | ||
− | {{collapse top | Unidade | + | {{collapse top | Unidade 4 - Introdução a linguagem VHDL e Quartus/ModelSim }} |
;Encontro 16 (21 set) - Linguagem VHDL: | ;Encontro 16 (21 set) - Linguagem VHDL: |
Edição das 12h11min de 21 de dezembro de 2023
Registro on-line das aulas
Unidade 1 - Introdução a disciplina
- 5 ENCONTROS
Unidade 1 - Introdução a disciplina |
---|
|
Unidade 2 - Sistema de numeração e códigos
- 4 ENCONTROS
Unidade 2 - Sistema de numeração e códigos | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
O ser humano precisa contar para determinar quantidades de coisas, com as quantidades ele pode fazer operações matemáticas e comparações.
Ler mais sobre Byte e os prefixos binários na Wikipedia
13 (decimal) = 01101 (binário sem sinal) -13 (decimal) = 10010 (binário em complemento de um) -13 (decimal) = 10010 + 1 = 10011 (binário em complemento de dois) -13 (decimal) = 11101 (binário em sinal-magnitude)
O código ASCII (American Standard Code for Information Interchange), é um padrão de codificação de caracteres para comunicação digital. Ele tem apenas 128 pontos de código, sendo 95 são caracteres imprimíveis e os demais são não imprimíveis (em azul no quadro abaixo), sendo usados para diversos controles de equipamentos eletrônicos. Atualmente esse código está sendo substituido pelos códigos UNICODE, que tem milhões de pontos de código, mas nos UNICODE os primeiros 128 são iguais ao conjunto ASCII.
Exemplo de leitura do quadro acima:
Descubra o que está escrito em: 45 6e 67 74 65 6c 65 63 6f 6d 20 64 6f 20 49 46 53 43 20 01000010 01101111 01101101 00100000 01100100 01101001 01100001 00100000 01110000 01100101 01110011 01110011 01101111 01000001 01001100 01001100
O Unicode é capaz de representar uma ampla variedade de caracteres, incluindo caracteres alfabéticos, numéricos, símbolos, caracteres especiais e até mesmo caracteres em idiomas e sistemas de escrita complexos, como chinês, árabe, hindi, hebraico, japonês, emojis entre outros. O Unicode possui um espaço de codificação grande o suficiente para suportar milhares de caracteres diferentes. O Unicode é implementado nos esquemas de codificação UTF-8, UTF-16 e UTF-32. O mais utilizado na web é o UTF-8, por ser eficiente em uso de número de bits e ser compatível com o ASCII. Hoje em dia o UTF-8 é usado em 98% de todos os websites conhecidos [1]. Para cobrir uma vasta gama de caracteres, o Unicode os organiza em blocos. Exemplos de blocos: "Latin basic","Greek and Coptic", "Chess Symbols", "Emoticons", "Mayan Numerals", etc.
Exemplo: Estender o número binário sem sinal de 5 bits "01101" para 8 bits: Número original: 01101 = (13 em decimal), pois 8 + 4 + 1 = 13 Número estendido: 00001101 = (13 em decimal), pois 8 + 4 + 1 = 13
Exemplo: Estender o número binário com sinal em complemento de 2 de 5 bits "10011" para 8 bits: Número original: 10011 = (-13 em decimal), pois -16 + 2 + 1 = -13 Número estendido: 11110011 = (-13 em decimal), pois -128 + 64 + 32 + 16 + 2 + 1 = -13
Exemplo: Estender o número binário com sinal em sinal-magnitude de 5 bits "10011" para 8 bits: Número original: 11101 = (-13 em decimal), pois -(+8 + 4 + 1) = -13 Número estendido: 10001101 = (-13 em decimal), pois -(+8 + 4 + 1) = -13
Os números de ponto flutuante são agrupados da esquerda para a direita:1) bit de sinal, 2) expoente e 3) mantissa. Para os formatos binários IEEE 754 (básico e estendido) que possuem implementações de hardware existentes, eles são distribuídos da seguinte forma:
Embora o expoente possa ser positivo ou negativo, em formatos binários ele é armazenado como um número sem sinal que possui um "viés" fixo adicionado a ele. A faixa de expoente para números normais é [−126, 127] para precisão simples, [−1022, 1023] para dupla. Existem três tipos principais de números: normalizados, denormalizados (ou desnormalizados) e especiais (como infinito e NaN - "Not a Number"). Nos formatos IEEE, o bit 1 inicial de um significando normalizado não é realmente armazenado. É chamado de bit "oculto" ou "implícito". Por causa disso, o formato de precisão simples na verdade tem um significando com 24 bits de precisão, o formato de precisão dupla tem 53. O layout para o ponto flutuante de 32 bits e de 64 bits são mostrados abaixo:
Exemplo: Dado o número floating point de 32 bits = 01000000111000000000000000000000 Sinal (msb): 0 => positivo Viés: (28-1 - 1) = -127 Expoente (8 bits): 10000001 = 129 - 127 = 2 Mantissa: (23 bits): 11000000000000000000000 Valor (24 bits): 1.11000000000000000000000 = 1,75 Resultado: (-) 1,75 x 22 = 7
Os números denormalizados não usam um "1" implícito no início da mantissa, ao contrário dos números normalizados. Isso significa que a mantissa dos números denormalizados começa com um "0" explícito antes da parte fracionária, permitindo representar valores muito pequenos que não podem ser normalizados devido à limitação dos bits do expoente.
Bit de sinal: 0 (positivo) Expoente: Todos os bits definidos como 1 (8 bits) Mantissa: Todos os bits definidos como 0 (23 bits) Representação em 32 bits: 0 11111111 00000000000000000000000
Bit de sinal: 1 (negativo) Expoente: Todos os bits definidos como 1 (8 bits) Mantissa: Todos os bits definidos como 0 (23 bits) Representação em 32 bits: 1 11111111 00000000000000000000000
Bit de sinal: Pode ser 0 ou 1 (geralmente usado para sinalizar erros ou operações indefinidas) Expoente: Todos os bits definidos como 1 (8 bits) Mantissa: Pelo menos um bit não nulo (23 bits) Representação: x 11111111 yyyyyyyyyyyyyyyyyyyyyyy (onde "x" é o bit de sinal e "y" são bits da mantissa)
|
Unidade 3 - Funções, portas lógicas e álgebra booleana
- 10 ENCONTROS
Unidade 3 - Funções, portas lógicas e álgebra booleana |
---|
|
Unidade 4 - Introdução a linguagem VHDL e Quartus/ModelSim
- 6 ENCONTROS
Unidade 4 - Introdução a linguagem VHDL e Quartus/ModelSim |
---|
library library_name;
use library_name.package_name.all;
entity entity_name is
[generic (
cons_name1: const_type const_value;
cons_name2: const_type const_value;
...
cons_nameN: const_type const_value);]
[port (
signal_name1: mode signal_type;
signal_name2: mode signal_type;
...
signal_nameN: mode signal_type);]
[declarative_part]
[begin
statement_part]
end [entity] [entity_name];
architecture arch_name of entity_name is
[declarative_part]
begin
statement_part
end [architecture] [arch_name];
library std;
use std.standard.all;
entity nand_gate is
port (a, b: in bit; x: out bit);
end entity;
architecture nome_arch of nand_gate is
begin
x <= a nand b;
end architecture;
Acesse a nuvem do IFSC usando um terminal via ssh: USER=LOGIN_SIGAA ssh $USER@quartus.sj.ifsc.edu.br -XC Insira a senha do SIGAA LOGIN_SIGAA@quartus.sj.ifsc.edu.br's password:
Abra o Quartus Prime digitando no terminal quartus20.1.sh Em seguida abra um arquivo para inserir o código VHDL. No menu superior selecione [File > New > Design Files: VHDL File] e [OK]
/home/USER/PASTA_DO_PROJETO/
nand_gate
nand_gate
Realize a Analysis & Synthesis [Processing > Start > Start Analysis & Synthesis], ou use um dos botões que o professor mostrou em aula.
Y = AB + AC' Z = A'BC + C' |
Unidade 4 - Circuitos lógicos combinacionais (com VHDL)
- 12 ENCONTROS
Unidade 4 - Circuitos lógicos combinacionais (com VHDL) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
-------------------------
-- File: bin2gray_v1.vhd --
-------------------------
entity bin2gray_v1 is
port
(
b0, b1, b2, b3 : in bit;
g0, g1, g2, g3 : in bit
);
end entity;
--Exemplo implementando o circuito diretamente com as portas lógicas
architecture ifsc_v1 of ____ is
begin
end architecture;
Como o circuito de um conversor bin2gray, possui uma certa quantidade de bits de entrada e a mesma quantidade de saída, não é adequado descrever esse circuito utilizando o tipo bit. O VHDL dispõe do tipo bit_vector; de vetores para descrever esse tipo de entrada e saída. -------------------------
-- File: bin2gray_v2.vhd --
-------------------------
entity bin2gray_v2 is
port
(
b : in bit_vector(3 downto 0);
g : out bit_vector(3 downto 0)
);
end entity;
--Exemplo implementando o circuito diretamente com as portas lógicas
architecture ifsc_v2 of ____ is
begin
end architecture;
Caso se deseje aumentar o número de bits da entrada, na abordagem acima é necessário aumentar o número de operações ou exclusivo, e para cada quantidade de bits é necessário ter uma nova descrição. Usando corretamente a instrução generic, e a instrução for generate, é possível escrever um código único (genérico) para qualquer numero de bits.
[generic (
cons_name1: const_type const_value;
cons_name2: const_type const_value;
...
cons_nameN: const_type const_value);]
label: FOR identificador IN faixa GENERATE
[Parte_Declarativa
BEGIN]
Instruções_concorrentes
...
END GENERATE [label];
-------------------------
-- File: bin2gray_v3.vhd --
-------------------------
entity bin2gray_v3 is
generic (N : natural := 4 );
port
(
b : in bit_vector(N-1 downto 0);
g : out bit_vector(N-1 downto 0)
);
end entity;
architecture ifsc_v3 of ____ is
begin
end architecture;
Considerando o que aprendeu com as duas versões do conversor bin2gray, descreva o circuito do conversor gray2bin. -------------------------
-- File: gray2bin.vhd --
-------------------------
entity gray2bin is
generic (N : natural := 4 )
port
(
g : in std_logic_vector(____)
b : out std_logic_vector(____)
)
end entity
architecture ifsc_v1 of ____ is
begin
end architecture
architecture ifsc_v2 of ____ is
begin
end architecture
Um multiplexador digital de N entradas e 1 saída, frequentemente abreviado como MUX N:1, é um circuito digital muito utilizado para rotear sinais digitais Ele desempenha a função de selecionar uma das entradas para ser encaminhada para a saída com base em um sinal de seleção (ou controle).
A tabela verdade que descreve um MUX2:1 é mostrada abaixo:
O MUX2:1 também pode ser representado de forma resumida por:
Onde o X0 e X1 na entrada podem assumir os valores 0 ou 1, e o simbolo "-" corresponde ao don't care (em VDHL) A função booleana que descreve a operação de um MUX 2:1 pode ser representada da seguinte forma:
O MUX4:1 pode ser representado de forma resumida pela tabela verdade:
A função booleana que descreve a operação de um MUX 4:1 pode ser representada da seguinte forma:
entity mux4x1 is
port
(
-- Input ports
X: in bit_vector (3 downto 0);
Sel : in bit_vector (1 downto 0);
-- Output ports
Y : out bit
);
end entity;
-- Implementação com lógica pura
architecture v_logica_pura of mux4x1 is
begin
Y <= (X(0) and (not Sel(1)) and (not Sel(0))) or
...
end architecture;
No entanto, o MUX4:1 também pode ser descrito utilizando a instrução WHEN-ELSE <optional_label>: <target> <=
<value> when <condition> else
<value> when <condition> else
<value> when <condition> else
...
<value>;
Warning (13012): Latch ... has unsafe behavior
No caso do MUX4:1 ele poderia ser descrito como: -- Implementação com WHEN ELSE
architecture v_WHEN_ELSE of mux4x1 is
begin
Y <= X(0) when Sel = "00" else
X(1) when Sel = "01" else
X(2) when Sel = "10" else
X(3);
end architecture;
Outra forma de descrever o MUX4:1 seria utilizando a instrução WITH-SELECT <optional_label>: with <expression> select
<target> <=
<value> when <choices>,
<value> when <choices>,
<value> when <choices>,
...
<value> when others;
Error (10313): VHDL Case Statement error ...: Case Statement choices must cover all possible values of expression
-- Implementação com WITH SELECT
architecture v_WITH_SELECT of mux4x1 is
begin
with Sel select
Y <= X(0) when "00", -- note o uso da ,
X(1) when "01",
X(2) when "10",
X(3) when others; -- note o uso de others, para todos os demais valores.
-- Não pode ser substituido por "11" mesmo que o signal seja bit_vector.
end architecture;
-- Design Unit que associa a architecture com a entity
configuration cfg_ifsc of mux4x1 is
for v_logica_pura end for;
-- for v_WHEN_ELSE end for;
-- for v_WITH_SELECT end for;
end configuration;
Figura 2.1 - Código RTL do mux4x1 v_logica_pura Figura 2.2 - Código RTL do mux4x1 v_WHEN_ELSE Figura 2.3 - Código RTL do mux4x1 v_WITH_SELECT
Figura 2.4 - Technology Map do mux4x1 para a família Cyclone
Figura 2.5 - Elemento Lógico usado no mux4x1 para a família Cyclone (node properties)
No entanto se utilizarmos um dispositivo FPGA da família Aria 10, que tem LUT tem 6 entradas, será necessário apenas 1 LE, conforme ilustrado a seguir. Figura 2.5 - Technology Map do mux4x1 para a família Aria 10
-- Isso eh uma linha de comentario y <= a * b ; --o sinal y recebe o resultado da multiplicacao a x b
caracter: 'A' 'x' '#' (com aspas simples)
type string is array (positive range <>) of character;
string: "IFSC" "teste" "teste123"
elemento ("bit") único: '0' '1' 'Z' (entre aspas simples) vetor de elementos ("bits"): "0110" "101001Z" (entre aspas duplas) vetor de 1 elemento ("bit"): "0" "1" (entre aspas duplas) inteiros: 5 1101 1102 (sem aspas)
0 -> '0' 7 (em base 2) -> "0111" ou b"0111" ou B"0111" 1023 (em base 2) -> "001111111111" ou b"1111111111" ou B"1111111111"
44 (em base 8) -> 5*8^1 + 4*8^0 -> O"54" ou o"54" 1023 (em base 8)-> 1*8^3 + 7*8^2 + 7*8^1 + 7*8^0 -> o"1777" 8#1777#
1023 (em base 16) -> 3*16^2 + 15*16^1 + 15*16^0 = X"3FF" ou x"3FF" 16#3FF#
1023 -> 1023 ou 1_023 1000 -> 1000 ou 1_000 ou 1E3 ou 10#1000#
85 (em base 5) -> (3*5^2 + 2*5^1 + 0*5^0) -> 5#320# 1539 (em base 3) -> (2*3^2+0*3^1+1*3^0)*3^4 -> 3#201#E4
O objeto CONSTANT pode ser declarado na parte declarativa da ENTITY, ARCHITECTURE, PACKAGE, PACKAGE_BODY, BLOCK, GENERATE, PROCESS, FUNCTION e PROCEDURE. constant <constant_name> : <type> := <constant_value>;
-- Declarações comuns de constantes
constant GND : std_logic := '0';
constant VCC : std_logic := '1';
constant SSD_0 : std_logic_vector(0 to 6) := "1111110";
constant MAX : natural := 44;
O objeto SIGNAL pode ser declarado na parte declarativa da ENTITY, ARCHITECTURE, PACKAGE, BLOCK, GENERATE. Os sinais não podem ser declarados no código sequencial (PROCESS, FUNCTION e PROCEDURE), mas podem ser usados. -- Signal sem valor default
-- Para atribuir um valor a um signal use "<=" como operador.
signal <name> : <type>;
-- Signal com valor default
signal <name> : <type> := <default_value>;
-- Declarações comuns de signals
signal <name> : std_logic;
signal <name> : std_logic_vector(<msb_index> downto <lsb_index>);
signal <name> : integer;
signal <name> : integer range <low> to <high>;
O objeto VARIABLE (variável) só pode ser declarada e usada dentro do escopo no código sequencial (PROCESS, FUNCTION e PROCEDURE). -- Variables devem ser declarada em process ou subprogramas.
-- Para atribuir um valor a um variable use ":=" como operador.
-- Variable sem valor default.
variable <name> : <type>;
-- Variable com valor default.
variable <name> : <type> := <default_value>;
-- Declarações comuns de variables
variable <name> : std_logic;
variable <name> : std_logic_vector(<msb_index> downto <lsb_index>);
variable <name> : integer;
variable <name> : integer range <low> to <high>;
Exemplos de declaração de CONSTANT, SIGNAL, VARIABLE, inicializando o valor usando o agregados CONSTANT a: BIT_VECTOR(5 DOWNTO 0) := (OTHERS => '0'); -- "000000"
CONSTANT b: BIT_VECTOR(7 DOWNTO 0) := (7 => '0', OTHERS => '1'); -- "01111111"
CONSTANT c: BIT_VECTOR(7 DOWNTO 0) := (7 => '0', 6 DOWNTO 0 => '1'); -- "01111111"
CONSTANT d: BIT_VECTOR(7 DOWNTO 0) := "01111111";
SIGNAL e: STD_LOGIC_VECTOR(7 DOWNTO 0); -- Not initialized
SIGNAL f: STD_LOGIC_VECTOR(1 TO 8) := (2|3|8 => '1', 4 => 'Z', OTHERS => '0' ); -- "011Z0001"
VARIABLE g: BIT_VECTOR(1 TO 16); -- Not initialized
VARIABLE h: BIT_VECTOR(1 TO 16) := (1 TO 8 => '1', OTHERS => '0'); -- "1111111100000000"
A biblioteca standard.vhd define os tipos BIT, BIT_VECTOR, BOOLEAN, INTEGER, NATURAL, POSITIVE, CHARACTER, STRING. package standard is
type boolean is (false,true);
type bit is ('0', '1');
type severity_level is (note, warning, error, failure);
type integer is range -2147483647 to 2147483647;
type real is range -1.0E308 to 1.0E308;
type time is range -2147483648 to 2147483647
units
fs;
ps = 1000 fs;
ns = 1000 ps;
us = 1000 ns;
ms = 1000 us;
sec = 1000 ms;
min = 60 sec;
hr = 60 min;
end units;
subtype natural is integer range 0 to integer'high;
subtype positive is integer range 1 to integer'high;
type string is array (positive range <>) of character;
type bit_vector is array (natural range <>) of bit;
A biblioteca Std logic 1164.vhd define os tipos STD_(U)LOGIG, STD_(U)LOGIG_VECTOR. PACKAGE std_logic_1164 IS
TYPE std_ulogic IS ( 'U', -- Uninitialized
'X', -- Forcing Unknown
'0', -- Forcing 0
'1', -- Forcing 1
'Z', -- High Impedance
'W', -- Weak Unknown
'L', -- Weak 0
'H', -- Weak 1
'-' -- Don't care
);
TYPE std_ulogic_vector IS ARRAY ( NATURAL RANGE <> ) OF std_ulogic;
SUBTYPE std_logic IS resolved std_ulogic;
TYPE std_logic_vector IS ARRAY ( NATURAL RANGE <>) OF std_logic;
A biblioteca Std logic 1164.vhd ainda define algumas funções importantes como a rising_edge que determina se um sinal está na borda de subida (usado em sinais de clock). -------------------------------------------------------------------
-- conversion functions
-------------------------------------------------------------------
FUNCTION To_bit ( s : std_ulogic; xmap : BIT := '0') RETURN BIT;
FUNCTION To_bitvector ( s : std_logic_vector ; xmap : BIT := '0') RETURN BIT_VECTOR;
FUNCTION To_StdULogic ( b : BIT ) RETURN std_ulogic;
FUNCTION To_StdLogicVector ( b : BIT_VECTOR ) RETURN std_logic_vector;
-------------------------------------------------------------------
-- edge detection
-------------------------------------------------------------------
FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN;
FUNCTION falling_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN;
-------------------------------------------------------------------
-- edge detection
-------------------------------------------------------------------
FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN IS
-- altera built_in builtin_rising_edge
BEGIN
RETURN (s'EVENT AND (To_X01(s) = '1') AND
(To_X01(s'LAST_VALUE) = '0'));
END;
A biblioteca Numeric std.vhd define os tipos UNSIGNED e SIGNED. package NUMERIC_STD is
type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
type SIGNED is array (NATURAL range <>) of STD_LOGIC;
A biblioteca Numeric std.vhd ainda define os operadores (abs, "+", "-", "*", "/", rem, mod, sll, slr, ror, rol), comparações ("=", '/=', ">", ">=", "<", "<=") e operadores lógicos (not, and, nand, or, nor, xor, xnor) para os tipos SIGNED e UNSIGNED. Além disso também define algumas funções muito utilizadas como: --============================================================================
-- RESIZE Functions
--============================================================================
function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED;
--============================================================================
-- Conversion Functions
--============================================================================
function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
function TO_INTEGER (ARG: SIGNED) return INTEGER;
function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;
library ieee;
use ieee.std_logic_1164.all;
entity tri_state is
generic (N: NATURAL := 1);
port
(
input : in std_logic_vector(N-1 downto 0);
ena : in std_logic;
output : out std_logic_vector(N-1 downto 0);
);
end entity;
architecture tri_state of tri_state is
begin
output <= input when ena = '1' else "Z";
end architecture;
|
Unidade 5 - Circuitos aritméticos (com VHDL)
- 5 ENCONTROS
Unidade 5 - Circuitos aritméticos (com VHDL) | ||
---|---|---|
Para implementar circuitos aritméticos, ao invés de se descrever o circuito com portas lógicas conforme mostrado para somadores, subtratores, comparadores e multiplicadores, deve-se utilizar os operadores aritméticos, e o compilador realizará a escolha do melhor circuito para cada caso. Inicialmente apresentamos alguns exemplos utilizando dados do tipo integer. Para o uso do tipo integer, se não houver limitação da faixa de valores, o compilador entenderá que os sinais devem ter 32 bits, o que gera circuitos muito maiores que normalmente necessário. Assim, ao usar as entradas e saidas como integer sem range, o diagrama RTL mostrará que o circuito foi construido com 32 bits [31..0]. Nos dispositivos da familia Cyclone IV E serão utilizados 32 elementos lógicos para tal circuito. entity somador is
port (
a, b : in integer;
s : out integer;
end entity;
architecture ifsc of somador is
begin
s <= a + b;
end architecture;
Figura 4.1 - Código RTL do somador com tipo integer sem range Figura 4.2 - Technology Map do somador com tipo integer sem range Por isso, o uso correto do tipo integer, exige que se limite a faixa de valores (range 0 to 15), o que fará com que o compilador atribua para os sinais a quantidade correta de bits, gerando circuitos de tamanho adequado. Assim, ao usar as entradas e saidas como integer com range 0 to 15, o diagrama RTL mostrará que o circuito foi construido com 4 bits [3..0]. Nos dispositivos da familia Cyclone IV E serão utilizados 4 elementos lógicos para tal circuito. entity somador is
port (
a, b : in integer range 0 to 15;
s : out integer range 0 to 15);
end entity;
architecture ifsc of somador is
begin
s <= a + b;
end architecture;
Figura 4.3 - Código RTL do somador com tipo integer com range Figura 4.4 - Technology Map do somador com tipo integer com range Para fazer uma subtração, basta trocar o operador "+" pelo "-", e o compilador irá implementar um subtrator realizando o complemento 2 da entrada b. entity subtrator is
port (
a, b : in integer range 0 to 15;
s : out integer range 0 to 15);
end entity;
architecture ifsc of subtrator is
begin
s <= a - b;
end architecture;
Figura 4.5 - Código RTL do subtrator com tipo integer com range Note nesta figura que as entradas b[3..0] são conectadas ao B[4..1] do somador, e que o B[0] é conectado ao Vcc ("1"). O mesmo ocorre com a entrada A. Ao mesmo tempo a entrada b é invertida, gerando assim o complemento de dois dessa entrada. Assim para realizar uma subtração pode ser utilizado o mesmo circuito do somador. Para fazer uma multiplicação, basta usar o operador "*"e o compilador irá implementar um multiplicador. Neste caso para evitar o overflow é importante definir o range da saída com um tamanho suficiente para comportar o maior produto entity multiplicador is
port (
a, b : in integer range 0 to 15;
s : out integer range 0 to 15*15);
end entity;
architecture ifsc of multiplicador is
begin
s <= a * b;
end architecture;
Figura 4.6 - Código RTL do multiplicador com tipo integer com range Note que esse circuito no Cyclone IV E necessita de 31 elementos lógicos, e no caso em que multiplicador tem entradas com 4 bits [3..0], a saída terá 8 bits [7..0] Caso a saída não tenha a quantidade suficiente de bits, haverá overflow e a resultado poderá estar incorreto. Caso se esqueça de limitar o range dos sinais de entrada, o compilador novamente assumirá que devem ser usada a faixa inteira dos inteiros (32 bis). Figura 4.7 - Código RTL do multiplicador com tipo integer sem range Note que esse circuito no Cyclone IV E aparentemente utiliza apenas 28 elementos lógicos, mas é importante observar que ele utiliza 6 dispositivo DSP (multiplicador de bits), os quais estão disponíveis dentro do FPGA. Se desativar o uso dos multiplicadores internos, forçando o uso dos elementos lógicos o total de elementos lógicos passará para 592, mostrando o desperdício de hardware que pode ocorrer. Para forçar o uso de elementos lógicos no lugar dos DSP realize a seguinte sequencia: Assignments > Settings > Compiler Settings > [Advanced Settings (Synthesis)] > Filter = DSP > DSP Block Balancing = Logic Elements > [OK]
Para fazer uma divisão, basta usar o operador "/" e o compilador irá implementar um divisor inteiro. O tamanho do quociente deve ser igual ao dividendo. entity divisor is
port (
dividendo : in integer range 0 to 15;
divisor : in integer range 0 to 3;
quociente : out integer range 0 to 15;
resto : out integer range 0 to 3
);
end entity;
architecture ifsc of divisor is
begin
quociente <= dividendo / divisor;
resto <= dividendo rem divisor;
end architecture;
Figura 4.8 - Código RTL do divisor com tipo integer com range Multiplicações e divisões por potências de 2 (2, 4, 8, 16, ... $2^N$) não necessitam de nenhum elemento lógico pois podem ser implementados pelo simples deslocamento dos signais. Figura 4.8 - Código RTL do multiplicador por 4 Figura 4.9 - Código RTL do divisor por 2 Multiplicações por constantes não precisam utilizar os multiplicadores, e são implementadas através de simples deslocamentos de sinais e somas. Assim multiplicar por 10 corresponde a multiplicar por 2 somar com a multiplicação por 8. Figura 4.10 - Código RTL do multiplicador por 10
package NUMERIC_STD is
type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
type SIGNED is array (NATURAL range <>) of STD_LOGIC;
A biblioteca Numeric std.vhd ainda define os operadores (abs, "+", "-", "*", "/", rem, mod, sll, slr, ror, rol), comparações ("=", '/=', ">", ">=", "<", "<=") e operadores lógicos (not, and, nand, or, nor, xor, xnor) para os tipos SIGNED e UNSIGNED. Além disso também define algumas funções muito utilizadas como: --============================================================================
-- RESIZE Functions
--============================================================================
function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED;
--============================================================================
-- Conversion Functions
--============================================================================
function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
function TO_INTEGER (ARG: SIGNED) return INTEGER;
function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;
FONTE: http://www.doulos.com/knowhow/vhdl_designers_guide/numeric_std/ Ler e guardar a página sobre Aritmética com vetores em VDHL
Fazer um circuito que detecte se existe alguma vaga vazia em um lote de 4 vagas. A entrada x(n) está baixo '0' se a vaga está vazia, e alto '1' se tem carro. A saída y estará alta '1' sempre que houver uma ou mais vagas vazias, e em baixo '0' se não houver nenhuma vaga. Para fazer este circuito, podemos testar cada posição da entrada x e verificar se alguma delas está com '0', e neste caso mudar a saída para '1', caso contrário a saída será '0'. Conforme veremos a seguir, é possível realizar diversas descrições em VHDL para esse circuito.
Testar cada uma das entradas x e verificar se há alguma delas com '0', então indicar que a saída é '1', senão a saída será '0'. library ieee;
use ieee.std_logic_1164.all;
entity vagas is
generic (N : natural := 4 );
port (
x : in std_logic_vector (N-1 downto 0);
y : out std_logic
);
end entity;
architecture ifsc_v1 of vagas is
begin
-- usando when-else
y <= '1' when x(0) = '0' else
'1' when x(1) = '0' else
'1' when x(2) = '0' else
'1' when x(3) = '0' else
'0';
end architecture;
Figura 4.12 - RTL do indicador de vagas com when-else Figura 4.13 - Technology Map do indicador de vagas Note neste Technology Map que para implementar esse circuito, o compilador deduziu que basta inverter as entradas X e realizar a operação OR sobre elas para determinar se tem ou não vagas. Fazendo a simulação do circuito podemos perceber que ele está funcionando, pois a saída y está em '1' sempre quando existe alguma vaga x(i) = '0'. A única situação em que a saída y está em '0' é quando todas as entradas estão em '1' (todas vagas ocupadas). Figura 4.14 - Simulação do indicador de vagas
Realizar uma operação ou sobre todas as entradas x invertidas. architecture ifsc_v2 of vagas is
begin
-- usando or e not
y <= (not x(0)) or (not x(1)) or (not x(2)) or (not x(3));
end architecture;
Figura 4.15 - RTL do indicador de vagas com portas NOT e OR Note que o Technology Map e a simulação produzem o mesmo resultado, apesar da descrição do hardware ser complemente diferente. Tanto na solução 1 como na 2, se tivermos mais vagas para verificar, será necessário alterar a descrição. Então para realizar uma descrição que seja genérica é necessário transformar essas soluções ou encontrar outras.
Realizar uma operação ou sobre todas as entradas x invertidas. Para tornar genérico o código use o for generate para fazer a operação de NOT e OR sobre as entradas. A seguir é apresentado o esboço da ideia, e fica por conta do estudante implementar essa solução. architecture ifsc_v3 of vagas is
signal tmp : std_logic_vector(N downto 0);
begin
tmp(0) <= '0'; -- inicializar tmp(0) com 0, pois nao afeta o resultado do OR.
-- use o for-generate para implementar de forma generica as seguintes linhas:
-- tmp(1) <= tmp(0) or (not x(0)); -- retorna 0 OR (not x0) => (not x0)
-- tmp(2) <= tmp(1) or (not x(1)); -- retorna (not x0) OR (not x1)
-- tmp(3) <= tmp(2) or (not x(2)); -- retorna (not x0) OR (not x1) OR (not x2)
--
-- tmp(i+1) <= tmp(i) or (not x(i));
-- ...
-- tmp(N) <= tmp(N-1) or (not x(N-1)); -- retorna (not x0) OR (not x1) ... OR (not xN)
y <= tmp(N); -- tmp(N) tem o resultado, precisa ser enviado para a saida y.
end architecture;
|
- Encontro 39 (14 dez.)
- Avaliação A2 (Unidades 4 e 5).
- Encontro 40 (19 dez.)
- Avaliação REC1 e REC2 (Unidades 1 a 5).
Avaliações
Durante o semestre serão realizadas 4 avaliações. As avaliações devem ser enviadas pela plataforma Moodle com os arquivos solicitados.
- Data das avaliações
- A1 - : dividida em 3 avaliações A1a (Sistemas Numéricos e códigos), A1b (Funções e portas lógicas), A1c (Álgebra booleana e simplificação de funções lógicas, mapa de Karnaugh)
- A2 - :
- R - Recuperação de A1 a A2 : dia 19/12
Atividade relâmpago (AR)
As atividades relâmpago devem ser entregues no Moodle da disciplina. A não entrega dessas atividades não gera nenhum desconto, apenas geram pontos de BÔNUS que são adicionados aos conceitos das avaliações A1 a AN.
Atividade extra-classe (AE)
A média ponderada das atividades extra-classe será considerada no cálculo do conceito final da UC. A entrega das mesmas será feita pelo Moodle, e cada dia de atraso irá descontar 0,2 na nota da atividade. Muitas dessas atividades também geram pontos de BÔNUS que são adicionados aos conceitos das avaliações A1 a AN. Para os BÔNUS só serão considerados projetos entregues no prazo.
Referências Bibliográficas: