VHDL - VHSIC Hardware Description Language Aula 2 Semântica de VHDL Leonardo Augusto Casillo Ivan Saraiva Silva 2003-2
Identificadores Usados como referência a todos os objetos declarados no código. Regras: Primeiro caractere deve ser uma letra (Obrigatório); o Ex: Teste, Teste123 Não são CASE-SENSITIVE (maiúsculas/minúsculas); o Ex: Teste = teste = TESTE Não é possível o uso de palavras reservadas com outras finalidades; o Ex: mux, and
Regras: Identificadores São permitidos apenas letras, números e underscore( _ ) Último caractere não pode ser underscore; o Ex: Teste_ Não são permitidos 2 underscores em seqüência; o Ex: Teste projeto Nomes com underscore são diferentes de nome sem underscore. o Ex: teste_projeto testeprojeto
Objetos de dados Usados para representar e armazenar dados; Três tipos básicos: constantes, sinais e variáveis; Cada objeto possui um tipo de dados específico e um conjunto de possíveis valores; Objetos de dados de tipos diferentes não podem ser atribuídos um ao outro. Ex: somar 101(Bit) e 011(Std_logic). Quando um valor é especificado(atribuição de um valor a um sinal ou variável ou um valor é transferido como parâmetro para um subprograma), este valor é representado na forma de um literal.
Constantes Assumem apenas um valor em todo o código. Declaração: constant <identificador>: <tipo> := <valor> Ex: constant errado : boolean := False; Ex: constant parte_ram : bit_vector(3 downto 0) := 1110; Podem ser declaradas em qualquer parte do código: Constante com valor global: Package (uso mais freqüente) Somente no contexto em que foi declarada: entity, architecture, process, function
Sinais Representam ligações entre elementos (aula anterior) Declaração: signal <identificador>: <tipo> [:= valor]; Podem ser declaradas: Globalmente: package Internamente: entity, architecture (mais utilizado)
Variáveis Utilizados para armazenar valores intermediários entre expressões; Atribuição imediata; Declaração: variable <identificador>: <tipo> [:= valor]; Podem ser declaradas apenas em processos (variáveis locais); Podem corresponder a registradores (processos sem temporização) ou não (processos com temporização);
FPGA & VHDL
Literais Valores de dados específicos usados como parâmetros de objetos ou dentro de expressões. Não representam tipos específicos: Ex: '1' pode representar um bit ou um caractere. São válidos dependendo do tipo: Ex: '$' é válido como um caractere mas não como bit.
Literais Podem ser representados pelas seguintes categorias: Character Literals: um caracter ASCII ( a, z ). String Literals: seqüência de caracteres ASCII ( texto ) Bit String Literals: formas especiais de string literals para representar valores das bases binária, octal e hexadecimal. B 100100 O 446 X A0F4B51 Válidos para bit_vector e std_logic_vector
Literais Numeric Literals: Integer Literals (Ex: 1) e Real Literals (Ex: 1.1) Números reais não são sintetizáveis. Based Literals: idêntico a numeric literals, mas utilizando bases binária, octal e hexadecimal. Ex: 2#101#, 16#FC9#, 2#1.0#E10# Physical Literals: grandeza física. Contém parte numérica e unidade. Podem representar tempo, velocidade, distância etc Ex: 300 s, 40 m
Tipos de dados São divididos em 4 classes: Tipos escalares (representam um único valor); Tipos compostos (representam uma coleção de valores); *Tipos de acessos (similares a ponteiros); *Tipos de arquivo (referencia objetos que contém uma seqüência de valores). * Não são sintetizáveis
Tipos Escalares Tipos enumerados: tipos já definidos pela norma: Bit Boolean Integer Real Physical STD_LOGIC
Tipos Escalares Tipos enumerados: permite criar novos tipos. Útil para máquina de estados (FSM) Ex: type estado is (inicio, espera, calculo, final); Os tipos criados podem ser declarados Ex: signal estado_atual : estado
Tipos Compostos ARRAY: Coleção de elementos do mesmo tipo Exemplos: type word is array (31 downto 0) of bit; type vetor is array(integer range <>) of real; type std_logic_vector is array(natural range <>) of std_logic;
Tipos Compostos Records: coleção de elementos de tipos diferentes. Semelhante a struct em C Exemplos: type instruction is record Mnemonico: string; Codigo: bit_vector(3 downto 0); Ciclos: integer; end record signal instrucao : instruction; instrucao.mnemonico : registrador instrucao.codigo : 0001 instrucao:ciclos : 3
Expressões Realizam operações sobre objetos do mesmo tipo; Operações lógicas: and, or, nand, nor, xor, xnor e not; Operações relacionais: igual (=), diferente (/=), menor que (<), menor ou igual (<=), maior que (>), maior ou igual (>=); Operações numéricas: soma (+), subtração (-), negação (- unário), multiplicação (*), divisão (/), módulo (mod), remanescente (rem), expoente (**) e valor absoluto (abs);
Expressões Operações de concatenação: Cria um novo vetor a partir de dois vetores já existentes. Ex: Dado1: bit_vector(7 downto 0); Dado2: bit_vector(7 downto 0); Dado_Resultante: bit_vector(7 downto 0) Dado1 := 01011011 ; Dado2 := 11010010 ; Dado_Resultante := (Dado1(7 downto 6) & Dado2(5 downto 2) & Dado1(1 downto 0)); Dado_Resultante = 01010011
Expressões
Atribuição de sinais Comandos utilizados para atribuir um dado valor a um sinal em função de um sinal de controle. Comando WITH - SELECT. Atribuição de sinal com escolha. Comando WHEN - ELSE Atribuição condicional de sinais. Utilizados fora de processos.
Comando WHEN - ELSE Exemplo: Multiplexador de 1 bit D0 D1 D 0 S MUX A D 1 S A D0, D1 = Entradas A = Sinal S = Saída
LIBRARY ieee; USE ieee.std_logic_1164.all; Multiplexador de 1 bit ENTITY Mux_1b IS PORT ( D0, D1, Sinal: IN BIT; Saida : OUT BIT ); END Mux_1b; É possível declarar portas do mesmo tipo em apenas uma linha Após a declaração da última porta não se usa ; O ; é declarado após o ) ARCHITECTURE behavior_we OF Mux_1b IS BEGIN Saida <= D0 WHEN Sinal = 0 ELSE D1 WHEN Sinal = 1 ; END behavior;
Decodificador 3-8 LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY decod3to8 IS PORT ( endereco : IN BIT_VECTOR(2 DOWNTO 0); Saida : OUT BIT_VECTOR(7 DOWNTO 0) ); END decod3to8; ARCHITECTURE behavior_we OF decod3to8 IS BEGIN Saida <= 00000001 WHEN endereco = 000 ELSE END behavior; 00000010 WHEN endereco = 001 ELSE 00000100 WHEN endereco = 010 ELSE 00001000 WHEN endereco = 011 ELSE 00010000 WHEN endereco = 100 ELSE 00100000 WHEN endereco = 101 ELSE 01000000 WHEN endereco = 110 ELSE 10000000 WHEN endereco = 111 ;
Comando WITH SELECT Exemplo: Multiplexador de 8 bits com 4 entradas D0 8 D1 8 MUX Saída D2 8 8 D3 8 Sinal 2
Multiplexador de 8 bits LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY Mux_8b IS PORT ( D0, D1, D2, D3 : IN BIT_VECTOR(7 DOWNTO 0); Sinal : IN BIT_VECTOR (1 DOWNTO 0); Saida : OUT BIT_VECTOR(7 DOWNTO 0) ); END Mux_8b; ARCHITECTURE behavior_ws OF Mux_8b IS BEGIN WITH Sinal SELECT Saida <= D0 WHEN 00, D1 WHEN 01, D2 WHEN 10, D3 WHEN 11 ; END behavior;
Multiplexador de 8 bits LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY Mux_8b IS PORT ( D0, D1, D2, D3 : IN STD_LOGIC_VECTOR(7 DOWNTO 0); Sinal : IN STD_LOGIC_VECTOR (1 DOWNTO 0); Saida : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ); END Mux_8b; ARCHITECTURE behavior_ws OF Mux_8b IS BEGIN WITH Sinal SELECT Saida <= D0 WHEN 00, D1 WHEN 01, D2 WHEN 10, D3 WHEN OTHERS; END behavior;
Decodificador 3-8 LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY decod3to8 IS PORT ( endereco : IN BIT_VECTOR(2 DOWNTO 0); Saida : OUT BIT_VECTOR(7 DOWNTO 0) ); END decod3to8; ARCHITECTURE behavior_ws OF decod3to8 IS BEGIN WITH endereco SELECT Saida <= 00000001 WHEN 000, 00000010 WHEN 001, END behavior; 00000100 WHEN 010, 00001000 WHEN 011, 00010000 WHEN 100, 00100000 WHEN 101, 01000000 WHEN 110, 10000000 WHEN 111 ;
Exercício: Multiplexador Estrutural Criar componentes AND, OR, NOT; Instanciar componentes; Realizar a ligação entre os componentes instanciados (PORT MAP);
Comando IF generate_label: IF expression GENERATE statement; statement; END GENERATE; Cláusula Generate Comando FOR: generate_label: FOR index_variable IN range GENERATE statement; statement; END GENERATE;
Comando IF Sequencia_reset: IF reset = 0 GENERATE a <= 0 ; b <= 0 ; END GENERATE; Exemplo Generate Comando FOR: Operacao_and: FOR indice IN (0 to 7) GENERATE Soma(indice) <= a(indice) and b(indice); END GENERATE;
Exemplo Somador 1 Bit A Vem_1 B (CARRY_IN) S Vai_ (CARRY_OUT
Exemplo Somador 1 Bit 1 0 0 1 0 1 1 0 SUM 1 1 1 1 1 0 1 1 1 1 0 1 0 0 0 1 1 1 1 0 0 0 1 0 0 1 0 0 0 0 0 0 COUT CIN B A SUM = A XOR B XOR CIN; COUT = ((A OR B) AND CIN) OR (A AND B);
LIBRARY ieee; Exemplo Somador 1 Bit USE ieee.std_logic_1164.all; ENTITY onebit_full_adder IS PORT (Cin, A, B : IN STD_LOGIC; Sum, Cout : OUT STD_LOGIC); END onebit_full_adder; ARCHITECTURE behavior OF onebit_full_adder IS BEGIN Sum <= a XOR b XOR Cin; Cout <= ((a OR b) AND Cin) OR (a AND b); END behavior;
Exemplo Somador 8 Bits utilizando o somador de 1 bit LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY eight_bits_adder IS PORT (Cin : IN STD_LOGIC; A : IN STD_LOGIC_VECTOR(7 DOWNTO 0); B : IN STD_LOGIC_VECTOR(7 DOWNTO 0); Sum : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); Cout : OUT STD_LOGIC); END eight_bits_adder;
Exemplo Somador 8 Bits utilizando o somador de 1 bit COUT CIN ADDER A SUM B COUT ADDER 7 CIN COUT A(7) ADDER 1 A(1) COUT ADDER 0 CIN A(0) S(7) B(7) S(1) B(1) S(0) B(0)
Exemplo Somador 8 Bits utilizando o somador de 1 bit ARCHITECTURE behavior OF eight_bits_adder IS SIGNAL Int_cout : STD_LOGIC_VECTOR(7 DOWNTO 0); COMPONENT onebit_full_adder PORT (Cin : IN STD_LOGIC; A : IN STD_LOGIC; B : IN STD_LOGIC; Sum : OUT STD_LOGIC; Cout : OUT STD_LOGIC); END COMPONENT;
Exemplo Somador 8 Bits utilizando o somador de 1 bit BEGIN Adder0 : onebit_full_adder PORT MAP ( Cin => Cin, A => A(0), B => B(0), Sum => Sum(0), Cout => Int_cout(0)); Adder1 : onebit_full_adder PORT MAP ( Cin => Int_cout(0), A => A(1), B => B(1), Sum => Sum(1), Cout => Int_cout(1));
Exemplo Somador 8 Bits utilizando o somador de 1 bit Adder2 : onebit_full_adder PORT MAP ( Cin => Int_cout(1), A => A(2), B => B(2), Sum => Sum(2), Cout => Int_cout(2)); Adder3 : onebit_full_adder PORT MAP ( Cin => Int_cout(2), A => A(3), B => B(3), Sum => Sum(3), Cout => Int_cout(3));
Exemplo Somador 8 Bits utilizando o somador de 1 bit Adder4 : onebit_full_adder PORT MAP ( Cin => Int_cout(3), A => A(4), B => B(4), Sum => Sum(4), Cout => Int_cout(4)); Adder5 : onebit_full_adder PORT MAP ( Cin => Int_cout(4), A => A(5), B => B(5), Sum => Sum(5), Cout => Int_cout(5));
Exemplo Somador 8 Bits utilizando o somador de 1 bit Adder6 : onebit_full_adder PORT MAP ( Cin => Int_cout(5), A => A(6), B => B(6), Sum => Sum(6), Cout => Int_cout(6)); Adder7 : onebit_full_adder PORT MAP ( Cin => Int_cout(6), A => A(7), B => B(7), Sum => Sum(7), Cout => Int_cout(7)); Cout <= Int_cout(7); END behavior;
Exemplo Somador Genérico (N-Bits) LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY nbits_adder IS GENERIC (N : POSITIVE := 8); -- Default value PORT (Cin : IN STD_LOGIC; A, B : IN STD_LOGIC_VECTOR(N-1 DOWNTO 0); Sum : OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0); Cout : OUT STD_LOGIC ); END nbits_adder;
Exemplo Somador Genérico ARCHITECTURE behavior OF nbits_adder IS SIGNAL int_carry : STD_LOGIC_VECTOR(N-1 DOWNTO 0); BEGIN Sum <= A(N-1 DOWNTO 0) XOR B(N-1 DOWNTO 0) XOR (int_carry(n-2 DOWNTO 0) & Cin); int_carry(0) <= ((A(0) OR B(0)) AND Cin) OR (A(0) AND B(0)); CASCADE_CARRY: FOR I in 1 TO N-1 GENERATE int_carry(i) <= ((A(I) OR B(I)) AND int_carry(i-1)) OR (A(I) AND B(I)); END GENERATE CASCADE_CARRY; Cout <= int_carry(n-1); END behavior;
Exemplo Somador Genérico Para interligar componentes genéricos: COMPONENT nbits_adder IS GENERIC (N : POSITIVE); PORT (Cin : IN STD_LOGIC; A, B : IN STD_LOGIC_VECTOR(N-1 DOWNTO 0); Sum : OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0); Cout : OUT STD_LOGIC); END COMPONENT; Adder : nbits_adder GENERIC MAP (N => 8) PORT MAP (cin, A(7 downto 0), B(7 downto 0), Saida(7 downto 0), cout);