Laboratório: Familiarização com o Quartus

Laboratório: Familiarização com o Quartus

Este laboratório é um tutorial para familiarização com a ferramenta Quartus. Ele também descreve uma sequência de passos que pode ser usada ao longo da disciplina para execução dos demais projetos. Leia as instruções e realize os passos.

Observação: Este tutorial funciona com as versões do Quartus até 20.1.1, a partir da qual o ModelSim foi descontinuado. Caso queira baixar na sua máquina, evite utilizar a versão mais recente, pois você encontrará o Questa que difere da interface do ModelSim.

Ver histórico de mudanças

Changelog

Versão Data Descrição
v2025.1 20/fev/2025 Versão inicial
v2025.2 02/mar/2025 Atualizadas imagens do quartus
v2025.2 12/mar/2025 Adicionado aviso sobre versão do quartus

Disciplina

Este laboratório faz parte da disciplina MC613 - Laboratório de Circuitos Digitais. Ver oferecimento mais recente.

Entrega

  • A entrega deverá estar em único arquivo .ZIP contendo todos e apenas os arquivos listados abaixo.
  • O nome do arquivo ZIP deve ser RA<RA>.zip, onde <RA> é o RA do componente do grupo que fará a entrega. Por exemplo, RA123456.zip é a entrega do grupo do aluno com o RA 123456.
  • Os nomes dos arquivos dentro do ZIP devem ser seguidos.
  • Se mais do que um arquivo for recebido para a mesma entrega, apenas o último recebido dentro do prazo será considerado.
  • O cumprimento ou não dessas instruções fará parte dos critérios de avaliação.

Arquivos que fazem parte da entrega:

  • hexcode.vhd: Entidade principal com os comentários em resposta ao pedido
  • diagrama.pdf: Diagrama de blocos da entidade principal
  • hexcode_tb.vhd: Test bench com os comentários em resposta ao pedido
  • modelsim.txt: Resposta ao pedido sobre a simulação com o Modelsim

Link para entrega: https://ic.unicamp.br/~isaias/mc613/entrega.

Atividades do laboratório

Parte I - Antes de começar

  1. Faça o download do manual da placa DE1-SoC. O arquivo está disponível na página de material complementar. Utilize-o como referência para todos os laboratórios. O manual contém informações sobre como funcionam e como utilizar cada um dos periféricos disponíveis na placa.

  2. Faça o download do arquivo de Pin Assignments que também está disponível como material complementar. Esse arquivo será necessário para facilitar o trabalho de configurar os projetos e gravar os circuitos na placa.

  3. Ao iniciar o Quartus pela primeira vez, poderá ser exibida a tela abaixo. Escolha a opção “Run the Quartus Prime software” para prosseguir com a licença gratuita do Quartus.

Inicialização do Quartus

Se essa acima janela não aparecer, é recomendável apagar a pasta .altera.quartus do seu home folder para descartar todas as configurações feitas para versões anteriores do Software.

  rm -rf /home/<turma>/<ra######>/.altera.quartus

Se tudo der certo, você deverá ver a janela principal do Quartus:

Janela principal do Quartus

  1. Verifique a configuração do caminho para a instalação do simulador Modelsim. Dentro da janela principal do Quartus, selecione Tools > Options… Selecione a aba EDA Tool Options e configure o caminho para a ferramenta ModelSim-Altera. O caminho é /opt/altera/17.1/modelsim_ase/linuxaloem.

Configuração do caminho para o Modelsim

Parte II - Criando um projeto no Quartus

  1. Da janela principal do Quartus, selecione File > New Project Wizard… Na janela New Project Wizard, pressione Next > até chegar na janela de configuração do projeto. Configure conforme abaixo:
  • Directory: caminho onde o projeto será salvo;
  • Name: um nome para o projeto – por exemplo, Lab0;
  • Top-Level Entity: a entidade (módulo) que será a primeira da hierarquia do projeto, aquela que se comunicará diretamente com os pinos de entrada e saída da placa DE1-SoC. Essa configuração pode ser modificada posteriormente.

Dicas:

  • Não utilize nomes de projeto e nomes de entidade muito longos ou que contenham espaços ou caracteres especiais.
  • VHDL não é case sensitive. Portanto, não utilize letras maiúsculas e minúsculas para diferenciar nomes de entidades (como a top-level).
  • Evite utilizar caminhos de diretório muito longos, que contenham caracteres especiais e, se possível, espaços.
  • Evite utilizar diretórios em dispositivos mais lentos, como pendrives e unidades mapeadas em rede – isso inclui o seu home folder!. Se viável, deixe para trabalhar em uma pasta local temporária na máquina (/temp) e copiar os arquivos depois. O processo de compilação do Quartus gera muitos arquivos e arquivos grandes. Utilizar dispositivos lentos pode prejudicar o processo.

Configuração de um novo projeto
TODO: Atualizar screenshoot. A imagem mostra o nome Lab01, porém este é o Lab0.

  1. Avance selecionando Next > até chegar na janela Family, Device & Board Settings. Selecione a aba Board e procure na lista pela placa que usaremos, DE1-SoC Board. Após selecionar, confirme clicando em Finish.

Configuração de placa

Configuração de placa

  1. De volta à janela principal do Quartus, selecione Assignments > Import assignments…. Na janela Import Assignments, busque o arquivo de Pin assignments que você baixou da página de material complementar e confirme clicando em OK. Você pode desmarcar a caixa Copy existing assignments into ***.bak before importing.

Importando os Pin Assignments

  1. Em Assignments > Assignment Editor, veja a lista de assignments que você acabou de importar. Os assignments são as associações entre os pinos de conexão da FPGA na placa DE1-SoC e os periféricos traduzidos como nomes de sinais que representam o que é cada elemento. A coluna To mostra os nomes dos sinais que devem ser usados como sinais de entrada e saída na entidade top-level do projeto. Os nomes dos sinais são os mesmos listados no manual da placa que você baixou da página de material complementar.

Lista de Pin Assignments

Assim, para utilizar os pinos de entrada e saída da placa, basta definir em VHDL entradas e saídas com os nomes listados no arquivo de pin assignments. Por exemplo, para utilizar os switches (botões) da placa, basta criar um vetor de 10 posições chamado SW:

SW: in std_logic_vector(9 downto 0)

Assim, o sinal em VHDL SW(3) estará associado ao local SW[3] e ao pino PIN_AF10.

  1. De volta à janela principal do Quartus, selecione Assignments > Settings…. Nas abas Category, à esquerda, selecione VHDL Input dentro de Compiler Settings. Ajuste VHDL version para VHDL 2008. A versão 2008 do VHDL permite utilizar construções que não existiam em versões anteriores. Confirme clicando em OK.

Note que, dependendo da resolução da tela, o botão OK pode não aparecer porque a janela não cabe na tela. Nesse caso, você pode precisar usar artifícios como redimensionar a janela, maximizar a janela, ocultar a barra de tarefas do Windows ou repensar seriamente suas escolhas de vida ao usar o Quartus para poder ver o botão.

Configuração VHDL 2008

  1. A janela Settings permite alterar outras configurações importantes do projeto criado. Por exemplo, na aba General pode ser alterado o nome da entidade top-level; na aba Libraries podem ser adicionadas e removidas bibliotecas adicionais e criadas bibliotecas customizadas para projetos maiores; na aba Files podem ser conferidos os arquivos adicionados, o caminho para cada um, a biblioteca que eles pertencem e a ordem em que eles são compilados, assim como adicionados e removidos arquivos; e o botão Device/Board… no canto superior direito permite alterar o dispositivo escolhido no momento da criação do projeto.

Parte III – Gerenciando arquivos no projeto

  1. Para criar novos arquivos VHDL, selecione File > New… e VHDL File dentro de Design Files. Ao salvar o arquivo pela primeira vez, o Quartus exibirá uma caixa com a opção Add file to current project para adicionar o novo arquivo diretamente ao projeto.

  2. Para ver e navegar pelos arquivos do projeto, selecione a opção Files no menu drop-down do painel Project Navigator. Se o painel Project Navigator não estiver visível, ative-o em View > Utility Windows > Project Navigator.

Ver arquivos no Project Navigator

  1. Para adicionar arquivos já existentes ao projeto, selecione Assignments > Settings… e vá na aba Files do painel à esquerda.

Dicas:

  • Procure criar um arquivo para cada entidade VHDL que for utilizar, e nomear o arquivo com o mesmo nome da entidade que está descrita nele.
  • Se for criar múltiplas entidades em um mesmo arquivo, note que as declarações de bibliotecas (por exemplo, library ieee e use ieee.std_logic_1164.all) devem ser repetidas antes de cada declaração de entidade.
  • Procure copiar os arquivos VHDL que for utilizar no projeto para dentro da pasta do projeto. Se for utilizar arquivos que estão em outras pastas, preste atenção nos caminhos e tome cuidado para não adicionar várias vezes o mesmo arquivo ao projeto.
  • Não utilize nomes de arquivos muito longos ou que contenham espaços ou caracteres especiais.
  • VHDL não é case sensitive. Portanto, não utilize letras maiúsculas e minúsculas para diferenciar nomes de entidades.
  • A ordem em que os arquivos aparecem na aba Files importa. O quartus considera os arquivos na ordem em que eles estão listados ali, e isso faz diferença principalmente para simulação. Portanto, deixe os arquivos listados de maneira que os arquivos que estão mais para baixo na lista dependam apenas de arquivos que estão mais para cima.
  1. Crie um arquivo chamado hexcode.vhd com o conteúdo abaixo, que descreve uma entidade chamada hexcode. Adicione a nova entidade ao projeto. Vamos analisar o código.
library ieee;
use ieee.std_logic_1164.all;

entity hexcode is
port (
  LEDR: out std_logic_vector(9 downto 0);
  SW: in std_logic_vector(9 downto 0);
  HEX5: out std_logic_vector(0 to 6);
  KEY: in std_logic_vector(3 downto 0)
  );
end entity hexcode;

architecture bhv of hexcode is
begin

  LEDR <= SW;
  
  with KEY select
  HEX5 <= "0000001" when "0000",
      "1001111" when "0001",
      "0010010" when "0010",
      "0000110" when "0011",
      "1001100" when "0100",
      "0100100" when "0101",
      "0100000" when "0110",
      "0001111" when "0111",
      "0000000" when "1000",
      "0000100" when "1001",
      "0001000" when "1010",
      "1100000" when "1011",
      "0110001" when "1100",
      "1000010" when "1101",
      "0110000" when "1110",
      "0111000" when "1111",
      "1111111" when others;

end architecture bhv;

Responda, pesquisando sobre o que achar necessário esclarecer melhor. Inclua as respostas como comentários no topo do arquivo hexcode.vhd.

  • Em que periféricos da placa DE1-SoC ela está conectada?
  • Por que a saída HEX5 foi declarado como um vetor 0 to 6 ao invés de 6 downto 0, como os demais? Que diferença faria uma declaração diferente no restante do código?
  • O que os valores atribuídos ao sinal HEX5 significam?
  • Qual a saída esperada (em valores binários) das saídas HEX5 e LEDR em função das entradas KEY e SW?
  • Qual o comportamento esperado do circuito quando gravado na placa DE1-SoC?
  1. Desenhe um diagrama de blocos em alto nível da entidade hexcode e salve em um novo arquivo diagrama.pdf.

Parte IV – Simulando um circuito com um test bench

  1. Crie o arquivo hexcode_tb.vhd e adicione-o ao projeto com o código a seguir. O arquivo descreve a entidade hexcode_tb, que é um test bench para a entidade hexcode. Um test bench é um código em VHDL que instancia um circuito para teste e aplica nele conjuntos de entradas com o objetivo de observar as saídas.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;

entity hexcode_tb is
end entity hexcode_tb;

architecture tb of hexcode_tb is
  signal leds: std_logic_vector(9 downto 0);
  signal sw: std_logic_vector(9 downto 0) := (others => '0');
  signal hex: std_logic_vector(0 to 6);
  signal keys: std_logic_vector(3 downto 0) := (others => '0');
  
  signal clock: std_logic := '0';
  signal stop: std_logic;
begin

  uut: entity work.hexcode port map(LEDR => leds, SW => sw, HEX5 => hex, KEY => keys);
  
  clock <= not clock after 5 ns when stop = '0' else '0';
  stop <= '1' when sw = (sw'range => '1') and keys = (keys'range => '1') else '0';
  
  process(clock)
  begin
    if clock'event and clock = '1' and stop = '0' then
      sw <= std_logic_vector(to_unsigned(to_integer(unsigned(sw)) + 1, sw'length));
      keys <= std_logic_vector(to_unsigned(to_integer(unsigned(keys)) + 1, keys'length));
    end if;
  end process;
end architecture tb;

Responda, pesquisando sobre o que achar necessário esclarecer melhor. Inclua as respostas como comentários no topo do arquivo hexcode_tb.vhd.

  • Por que a entidade hexcode_tb não tem entradas e saídas?
  • Como é feita a instanciação da entidade hexcode dentro do test bench? Por que não são usados pacotes (VHDL package) e declaração de componentes (component)? O que significa a inscrição uut: e para que ela serve?
  • O que significa a palavra-chave work ao lado do nome da entidade instanciada?
  • Qual a função dos pacotes std_logic_unsigned e numeric_std no código?
  • Qual o significado dos prefixo 'range, 'length e 'event nos sinais sw, keys e clock e por que eles são usados?
  • Quais são os padrões de entrada aplicados aos sinais SW e KEY?
  • Quais são as saídas esperadas para o teste?
  1. Para simular o test bench, precisamos primeiro configurá-lo. Selecione a opção RTL Simulation no menu drop-down do painel Tasks. Se o painel Tasks não estiver visível, ative-o em View > Utility Windows > Tasks.

RTL Simulation no painel Tasks

  1. Expanda a opção RTL Simulation dentro do painel (não no menu drop-down) e dê um clique duplo em Edit Settings.
  • Configure Tool name como ModelSim-Altera.
  • Em EDA Netlist Writer settings, configure Format for output netlist como VHDL.
  • Em NativeLink settings marque a opção Compile test bench.

Configuração de Simulação RTL

  1. Clique no botão Test Benches… ao lado do menu drop-down Compile test bench. Na janela Test Benches que aparecerá, clique em New…. Você verá a janela New Test Bench Settings.
  • Em Test bench name dê um nome para o seu teste, por exemplo, hexcode_tb.
  • Em Top level module in test bench dê o nome da entidade que efetuará o teste (não daquela que está sendo testada), no caso, hexcode_tb.
  • Em Simulation period, deixe marcado Run simulation until all vector stimuli are used. Isso significa que o simulador parará automaticamente quando os sinais do código de teste pararem de variar. Note que, alternativamente, você pode especificar um tempo em End simulation at.
  • Em Test bench and simulation files adicione os arquivos necessários para o teste, no caso hexcode.vhd e hexcode_tb.vhd, nesta ordem.
  • Confirme tudo clicando em OK nas janelas New Test Bench Settings, Test Benches e Settings.

Configuração de um test bench

  1. Para executar a simulação, selecione a opção RTL Simulation no menu drop-down do painel Tasks e dê um clique duplo em RTL Simulation dentro do painel. O Quartus executará automaticamente a operação Analysis & Elaboration (você verá uma barra de progresso) e, logo após, abrirá o simulador ModelSim para simular o projeto. Se ao invés de ver o ModelSim você vir uma mensagem de erro, confira a configuração de caminho para o ModelSim altera conforme o item I-4. A janela do ModelSim se parecerá com a imagem abaixo. Se painéis estiverem faltando na sua visualização, selecione Layout > Reset.

Janela principal do Modelsim

  1. Tome um tempo para analisar a janela do ModelSim e entender o que os controles fazem. Algumas atividades interessantes que podem ser úteis são:
  • Acompanhar possíveis erros e warnings de simulação no painel inferior. Em VHDL, warnings são muito importantes e várias vezes indicam o que há de errado em um projeto que “não funciona”.
  • Diminuir e aumentar o zoom da visualização da onda de simulação nos botões com os ícones da lupa.
    Botões de zoom no Modelsim
  • Ir para a próxima ou anterior transição de um sinal, na onda, clicando sobre o nome dela e usando os botões.
    Botões de bordas de sinal no Modelsim
  • Alterar a base de visualização dos valores clicando com o botão direito sobre o nome do sinal e selecionando, em Radix, as opções para exibir os valores em decimal, hexadecimal, decimal sem sinal, etc.
  • Expandir a visualização de vetores para exibirem múltiplos sinais binários.
  • Reiniciar e re-executar a simulação com os botões Restart e Continue Run. Note que se a opção Run simulation until all vector stimuli are used na configuração do testbench não for utilizada ou os sinais de simulação nunca pararem de variar a simulação poderá rodar infinitamente. Clique no botão Stop para parar.
    Botões de controle de simulação no Modelsim
  • Incluir sinais internos da unidade em teste na simulação, clicando e arrastando-os entre os painéis mais à esquerda para a janela que exibe a onda. Pode ser necessário reiniciar a simulação.

Note que existe algum problema recorrente no ModelSim que faz com que a simulação trave ou passe a exibir valores desconexos na onda de visualização sem motivo aparente. Isso geralmente acontece apenas na primeira visualização, logo após a janela do ModelSim aparecer. Por isso, quando estiver executando um teste e vir valores que não fazem sentido, antes de culpar o seu código, tente re-executar a simulação utilizando os botões do item IV-6.e para verificar se isso resolve o problema.

  1. Após analisar a simulação, responda, pesquisando sobre o que achar necessário esclarecer melhor. Envie as respostas em um arquivo de texto modelsim.txt.
  • Os padrões de entrada são os que você esperava? Se não, por quê?
  • Os padrões de saída são os que você esperava? Se não, por quê?
  • Que alterações seriam necessárias para comparar as saídas com um modelo que você sabe que está correto (“modelo golden”)?
  • Que alterações seriam necessárias para comparar com um modelo golden e contar o número de entradas que exibe valores de saída incorretos?
  • Que alternativas você propõe para tornar a visualização dos sinais mais fácil de ser interpretada? Elabore uma alternativa, especialmente, para o sinal hex.

Parte V – Sintetizando e gravando na placa

  1. Para sintetizar um circuito e gravar na placa, precisamos trocar o fluxo de trabalho para compilação (síntese). Em projetos de hardware, síntese e simulação são coisas muito diferentes. Na simulação, o código VHDL é tratado como um software, o que permite muitas construções que não são permitidas para síntese. Essas construções resultam em código “não-sintetizável”. É comum que desenvolvedores que começam a escrever o código apenas pensando em seu comportamento, e não em que tipo de módulos e dispositivos de hardware representa, acabem escrevendo código não-sintetizável. Também é comum que código que passe corretamente pelo fluxo de simulação nem consiga completar o fluxo de síntese ou, pior ainda, complete e, ao ser gravado na placa, apresente um comportamento inesperado ou que não faça o menor sentido. Por outro lado, utilizando simulação é muito mais fácil de analisar o comportamento do código ao ver sinais internos e suas relações. Por isso, os dois fluxos são importantes.

Para executar a síntese, de volta a janela principal do Quartus (o Modelsim deve ser fechado), selecione a opção Compilation no menu drop-down do painel Tasks e dê um clique duplo em Assembler (Generate programming files), após expandir o item Compile Design se necessário. Se o painel Tasks não estiver visível, ative-o em View > Utility Windows > Tasks.

  1. O Quartus executará automaticamente os procedimentos de Analysis & Synthesis, Fitter e Assembler. O primeiro faz a análise do código descrito e a síntese, o segundo mapeia o resultado utilizando os componentes disponíveis na placa e o terceiro formata o resultado em um arquivo para gravação. É normal que essas tarefas demorem muito mais que uma compilação de software, mesmo para designs pequenos. Porém, caso esteja demorando MUITO tempo, pode ser um indicativo de algo de errado com o código.

Se houver erros, verifique primeiro se a entidade top-level está configurada corretamente e o dispositivo utilizado é o correto. Se os erros persistirem, verifique-os no painel inferior ou abrindo as pastas referentes a cada um dos procedimentos e selecionando Messages na aba Compilation Report que se abrirá ao iniciar a compilação.

  1. Se não houver erros, com certeza haverá muitos warnings. Os warnings são exibidos de maneira agrupada no painel inferior e na aba de Compilation Report. Os warnings são muito importantes e ajudam muito a encontrar problemas no projeto. Não deixe de tomar um tempo para analisar os warnings e tentar entender o que eles significam.

Em especial, preste muita atenção em resolver warnings que indiquem a existência de “latches” ou “unsafe behavior” no projeto. Esses são os warnings que têm o potencial de causar maior frustração ao analisar o comportamento de um circuito, após gravação na placa, e não devem ser ignorados. Latches são geralmente gerados por construções condicionais que não cobrem um caso contrário, por exemplo, if sem else, when sem um else ou with/select que não cubra todas as possibilidades. Note que não basta apenas haver um else, mas ele tem que efetivamente dar um valor para os sinais envolvidos quando a condição do if/when não é atingida.

  1. Após executar o Assembler, o Quartus terá gerado os arquivos necessários para gravação do circuito na placa. Conecte a placa DE1-SoC no computador e na tomada e ligue-a no botão vermelho. A placa deverá exibir um código de teste piscando leds e mostrando números sequenciais nos visores. Se isso não acontecer, não prossiga e peça ajuda ao professor.

  2. Role um pouco o painel Tasks e dê um clique duplo em Program Device (Open Programmer). Você verá a janela do gravador na placa.

Se na parte superior esquerda da janela você vir a mensagem “No Hardware”, conforme a imagem abaixo, clique em Hardware Setup…. Caso contrário, se vir “DE1-SoC”, pule para o passo 7 desta parte.

Se a lista estiver vazia, é provável que o driver da placa não esteja corretamente instalado (Windows) ou que o seu usuário não tenha permissão para acessá-lo (Linux).

Mensagem de No Hardware no Programmer

  1. Na janela Hardware Setup, na tabela Available hardware items, dê um clique duplo sobre DE-SoC e confirme, clicando em Close.

Hardware Setup no Programmer

  1. De volta à janela principal do Programmer, clique no botão Auto Detect, à esquerda. Na janela Select Device, selecione a opção 5CSEMA5 e confirme. Depois, confirme a mudança de dispositivo clicando em Yes.

Configuração do device no Programmer

  1. Clique com o botão direito sobre a linha da tabela que contém o dispositivo 5CSEMA5 e clique em Change File. Navegue pela estrutura de pastas do seu projeto para a pasta output_files e selecione o arquivo *.sof que corresponde ao nome do projeto.

Trocando arquivo de programação no Programmer

  1. Marque a checkbox Program/Configure correspondente na tabela.

Instruindo programação do dispositivo

  1. Se tudo estiver correto, o botão Start deverá estar ativo e clicável. Basta clicar nele para gravar o circuito na placa.

  2. Verifique o funcionamento do circuito na placa e responda (para você mesmo, não é preciso entregar nada), pesquisando sobre o que achar necessário esclarecer melhor:

  • O comportamento do circuito é o que você esperava? Se não, por quê?
  • Que alterações seriam necessárias para atingir o comportamento que era esperado, se já não foi atingido?
  • O comportamento do circuito é o mesmo demonstrado pela simulação? Se não, por quê?