VHDL (outros tópicos) MO801/MC912
Outros tipos de portas Tipos já vistos in out Novos tipos inout buffer
inout Porta de entrada e saída Considerado um fio com possibilidade de escrita e leitura Quando é feita uma leitura, funciona como uma porta in Quando é feita uma escrita, funciona como uma porta out Como saber quando é in e quando é out?
buffer É uma porta de saída com um buffer que faz realimentação Considerado um fio com possibilidade de escrita e leitura Quando é feita uma leitura, o valor presente na porta é lido Quando é feita uma escrita, funciona como uma porta out
Aliases Permite que seja dado outro nome para um dado elemento Um campo dentro de um registro Um subconjunto de bits de um vetor de bits Tipo de dados Funções Podem ser definidos alias de alias Todas as operações aplicadas a um alias é aplicada ao elemento original
Exemplo type register_array is array(0 to 15) of bit_vector(31 downto 0); type register_set is record general_purpose_registers : register_array; program_counter : bit_vector(31 downto 0); program_status : bit_vector(31 downto 0); end record; variable CPU_registers : register_set; alias GPR is CPU_registers.general_purpose_registers; alias SP is GPR(15); alias PSW is CPU_registers.program_status; alias interrupt_level : bit_vector(4 downto 0) is PSW(30 downto 26);
Arquivos Existem dois arquivos do tipo text já abertos por padrão input Mapeado no dispositivo de entrada padrão (geralmente é o teclado) output Mapeado no dispositivo de saída padrão (geralmente é a tela)
Tipos Representação de inteiros sobre bits Package numeric_bit unsigned, signed Complemento de 2 (bit de sinal à esquerda) Package numeric_bit type unsigned is array (natural range <>) of bit; type signed is array (natural range <>) of bit; Package numeric_std type unsigned is array (natural range <>) of std_logic; type signed is array (natural range <>) of std_logic;
Conversões to_integer to_unsigned to_signed Converte signed para integer e unsigned para natural to_unsigned Converte natural para unsigned to_signed Converte integer para signed Mais detalhes no capítulo 8 do livro
Codificação de tipos enumerados Por padrão, é responsabilidade das ferramentas de síntese definir como serão codificados os tipos enumerados O projetista pode sobrepor esse padrão definindo o atributo enum_encoding attribute enum_encoding : string; type state is (idle, preamble, data, crc, ok, error); attribute enum_encoding of state : type is “000 001 010 011 100 111”; A ordem crescente deve ser mantida
Desligando a ferramenta de síntese A ferramenta de síntese pode ser desligada para alguns trechos de código Útil para incluir testes internamente nos modelos Dois comentários especiais controlam a ferramenta -- rtl_synthesis off -- rtl_synthesis on Algumas ferramentas também aceitam a versão -- pragma translate off -- pragma translate on
Exemplos extras Opções para o GHDL Comunicação com múltiplos domínios de freqüência Carga de memória para simulação Use alias para quebrar sinais Portas para banco de registradores
Opções do GHDL Analisar o código ghdl –a –ieee=synopsys arquivo.vhd Elaborar a entidade (gerar um executável) ghdl –e –ieee=synopsys arquivo Outras opções úteis i: Importa um arquivo para a biblioteca gen_makefile: cria um Makefile --vcd=arq.vcd: gera um arquivo no formato VCD com as formas de ondas (só é válido no executável)
Múltiplos domínios de freqüência Como fazer a comunicação de dois módulos que trabalham em freqüências diferentes? A 17 MHz B 22 MHz
Definir um protocolo O Clock não pode ser considerado Definir sinais de handshake para cada lado Usar registradores nos dois lados do canal de comunicação Cuidado com latches Funciona em situações simples Transporta o problema de temporização para dentro do circuito!
Situações específicas Sabe-se, antecipadamente, qual dos dois módulos é o mais rápido Se as freqüências são muito distintas, o problema fica mais simples Ex.: A trabalha com mais do que o dobro da freqüência de B
Carga de Memória em Simulação Como modelar uma ROM/RAM? Como simulá-la? Como carregar um valor inicial? Como fazer um mesmo módulo que seja útil na simulação e na síntese?
ROM Versão mais simples: Alternativa Vetor de constantes case sobre o endereço Fará com que a ferramenta de síntese tente otimizar a memória com lógica A temporização será modificada
Dicas Utilize os flags para desabilitar a ferramenta de síntese --rtl_synthesis off --rtl_synthesis on Inclua um generic no componente passando o nome do arquivo Permite que o mesmo componente seja usado mais de uma vez no projeto Não se esqueça de parametrizar o intervalo dos endereços e a largura dos dados também
Como zerar uma memória? Síntese Simulação Gastar ao menos N ciclos de clock para escrever N zeros na memória de N posições Simulação Declarar a memória com valor inicial zerado signal Memoria is array(0 to 255) of std_logic_vector(31 downto 0) := (others => (others => ‘0’));
Use alias para quebrar sinais Exemplos type TInstrucao is unsigned(15 downto 0); signal instrucao : TInstrucao; alias opcode : unsigned(3 downto 0) is instrucao(15 downto 12); alias rd : unsigned(3 downto 0) is instrucao(11 downto 8); alias imm12 : unsigned(11 downto 0) is instrucao(11 downto 0); Todos os acessos feitos serão considerados em relação ao sinal instrucao rd = imm12(11 downto 8) !
Portas para banco de registradores Quantas portas o banco de registradores acessado pela máquina de estados abaixo precisa? case estado is when A => val1 <= RB(end1); when B => val2 <= RB(end2); when C => val3 <= RB(end3); end case;
Sugestão de escrita Cuidado com a temporização! signal endereco, valor : … valor <= RB(endereco); … process … case estado is when A => endereco <= end1; val1 <= valor; when B => endereco <= end2; val2 <= valor; when C => endereco <= end3; val3 <= valor; end case; Cuidado com a temporização!