Mega Memória
O projeto descrito a seguir é um exemplo de circuito sequencial descrito em VHDL através de uma função do Quartus II, a Megafunção. Ela gera um componente a partir de especificações passadas pelo usuário através de um assistente, parecido com o utilizado para criar um projeto. Uma vez especificado, o assistente gera o componente e um template para a declaração e outro pra instanciação, o que torna possível a realização de um bloco de lógica complexo de forma rápida até mesmo para um usuário pouco experiente.
A lógica descrita neste projeto pode ser utilizada para implementação de projetos maiores.
Componentes utilizados:
- 1x Kit CPLD_7064;
- 1x Placa de Botões;
- 1x Placa de LEDs;
- 2x Placa de Chaves;
Lógica de Funcionamento
Figura 1 – Diagrama de Blocos do projeto.
A memória deve permitir tanto a escrtita quanto a leitura de dados.
Escrita
Para a escrita de dados, deve-se colocar o dado que se deseja escrever, o endereço no qual será escrito e manter o ESCRITA em nível lógico alto. Com um pulso de CLOCK IN, as entradas serão registradas então a escrita terá sido completa. Se quisermos ver o que foi escrito basta fornecer um pulso de CLOCK OUT.
Leitura
Para a leitura de dados, o ESCRITA deve estar em nível lógico baixo e deve-se colocar o endereço a ser lido. Um pulso de CLOCK IN fará com que o comando seja registrado. Um pulso de CLOCK OUT fará com que a saída seja atualizada e registrada.
Megafunção
Primeiramente, abrimos o MegaWizard. Abrimos a opção Tools e MegaWizard Plug-In Manager.
Figura 2 – Seleção da ferramenta.
Uma vez aberto, pode-se selecionar a opção de criar uma nova função. Observe que o Megawizard auxilia também na edição de megafunções já criadas e na criação de megafunções a partir de outras.
Figura 3 – Primeira etapa da criação da Mega Função.
Se selecionado para criar uma megafunção a partir do zero, deve-se selecionar o tipo Megafunção que se deseja. Esta etapa irá definir como o componente irá se comportar.
Figura 4 – Seleção do tipo de componente que se deseja.
Após a definição do modelo, podemos definir algumas características do comportamento. Neste caso, escolhemos a opção de registrar as entradas e as saídas da memória.
Figura 5 – Seleção de características.
Por ser uma memória, pode-se optar por dar um valor inicial para ela. Neste caso não será utilizado esta opção, porém em outros projetos cria-se um arquivo .mif ou .hex para gerar a memória com valores iniciais já estabelecidos, como no projeto VGA para FPGA.
Figura 6 – Seleção do valor inicial da memória.
O Megawizard adiciona bibliotecas para uma posterior simulação.
Figura 7 – Bibliotecas a serem adicionadas para a simulação.
Pode-se escolher os arquivos a serem criados pelo Megawizard. Ele possui a opção de gerar um arquivo em AHDL, um .bsf e um template da instanciação do componente criado.
Figura 8 – Arquivos que podem ser criados pelo Megawizard.
Após finalizar, o componente terá sido criado. Para utilizá-lo, basta adicionar ao projeto.
Mega Memória
Na entidade, definimos as estradas e saídas do projeto.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
library lpm; use lpm.lpm_components.all; entity MegaMemoria is port( ClockIn : in std_logic; ClockOut : in std_logic; Saida : out std_logic_vector(7 DOWNTO 0); Endereco : in std_logic_vector(1 downto 0); Dado : in std_logic_vector(7 DOWNTO 0); Escrita : in std_logic ); end entity MegaMemoria; |
Declaração do Componente
Depois, fazemos a declaração do componente. Podemos pegar o template gerado pelo Quartus II e colar diretamente na arquitetura.
Figura 9 – Template da declaração do componente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
architecture comportamento of MegaMemoria is component Memoria PORT ( address : IN STD_LOGIC_VECTOR (1 DOWNTO 0); data : IN STD_LOGIC_VECTOR (7 DOWNTO 0); inclock : IN STD_LOGIC ; outclock : IN STD_LOGIC ; we : IN STD_LOGIC := '1'; q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) ); end component; |
Instanciação do componente
Uma vez declarado o componente, vamos associar suas entradas e saídas com os sinais do projeto, de acordo com a lógica desejada. Mais uma vez o Quartus gera um template que pode facilitar bastante o trabalho.
Figura 10 – Template da instanciação do componente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
begin Memoria_inst : Memoria PORT MAP ( address => Endereco, data => Dado, inclock => ClockIn, outclock => ClockOut, we => not (Escrita), q => Saida ); end architecture comportamento; |
Simulação
Para a simulação, foram inseridos e lidos dados da memória seguindo a ordem necessária para tais operações. Foram feitas as seguintes operações:
- Escreveu-se o dado “10101010” no endereço “00”.
- Escreveu-se o dado “11001100” no endereço “01”.
- Leu-se o dado no endereço “00”.
- Leu-se o dado no endereço “01”.
Escrita
O código abaixo apresenta a simulação da escrita de um dado.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
-- Escrevendo "10101010" no endereco "00" Endereco <= "00"; Dado <= "10101010"; wait for 20 us; Escrita <= '0'; -- Aperta o botão de escrita wait for 10 us; ClockIn <= '0'; -- Aperta o botão de clockIn wait for 10 us; ClockIn <= '1'; -- Solta o botão de ClockIn -- Com este pulso de ClockIn, o dado já foi gravado. wait for 5 us; Escrita <= '1'; -- Solta o botão de escrita wait for 5 us; |
Leitura
O código abaixo apresenta a simulação da escrita de um dado.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
-- Lendo o dado escrito no endereco "00" Endereco <= "00"; ClockIn <= '0'; -- Aperta o botão de ClockIn wait for 10 us; ClockIn <= '1'; -- Solta o botão de ClockIn wait for 5 us; ClockOut <= '0'; -- Aperta o botão de ClockOut wait for 10 us; ClockOut <= '1'; -- Solta o botão de ClockOut wait for 10 us; |
Os nomes utilizados no testbench foram os mesmos utilizados no projeto, lembrando que isso não é necessário e a atribuição depende da ordem em que aparece no projeto e na declaração de UUT. O resultado da simulação pode ser visto abaixo na janela do ModelSim-Altera:
Figura 11 – Simulação da Mega Memória
Estrutura Física
Figura 12 – Montagem do projeto.
O projeto implementado utiliza um kit CPLD 7064, onde será gravado o projeto. A placa de LEDs irá com CON1, as duas placas de chaves no CON2 e CON3 e a placa de botões no CON4.
Montagem e Roteamento
A montagem pode ser feita como na ilustração abaixo, feita no Fritizing:
Figura 13 – Esquema proposto.
Com base na montagem feita e na pinagem da placa, podemos definir a pinagem do componente:
Figura 14 – Pinagem proposta para o projeto.
Arquivos do Projeto
Para o download do projeto completo, clique aqui.
O arquivo está no formato “zip”, e inclui, entre outros:
– O arquivo de projeto do Quartus “.qpf”
– A descrição no formato VHDL “.vhd”
– O Testbench no formato VHDL “.vhd”
– O arquivo para gravação do CPLD, no formato “.pof”.