Cobertura em SystemVerilog: Métricas e Técnicas Eficientes

Neste tutorial, vamos explorar como definir e ajustar métricas de cobertura em SystemVerilogIntrodução ao SystemVerilog: História e EvoluçãoIntrodução ao SystemVerilog: História e EvoluçãoDescubra a trajetória do SystemVerilog, sua origem a partir do Verilog, e os marcos que transformaram a verificação de hardware na indústria digital. para tornar o processo de verificação mais eficiente. Veremos as construções essenciais, desde a criação de covergroups até a configuração de coverpoints, seus bins e opções avançadas que permitem controlar metas (goals) e pesos de cobertura (weights). Ao final, você será capaz de aplicar essas técnicas de forma prática nos seus projetosIntrodução ao SystemVerilog: História e EvoluçãoIntrodução ao SystemVerilog: História e EvoluçãoDescubra a trajetória do SystemVerilog, sua origem a partir do Verilog, e os marcos que transformaram a verificação de hardware na indústria digital., garantindo uma análise detalhada de como o design está sendo exercitado pelos testes.

Visão Geral de Cobertura em SystemVerilog🔗

A cobertura em SystemVerilog fornece recursos para identificar se as diversas condições, cenários e transições nos sinais do seu design estão sendo exercitados adequadamente. Aqui, focaremos na cobertura funcionalCobertura Funcional vs. Cobertura de Código: Definições e ImportânciaCobertura Funcional vs. Cobertura de Código: Definições e ImportânciaDescubra como as coberturas funcional e de código fortalecem testes em SystemVerilog, garantindo qualidade e a execução completa do design., que é realizada por meio de covergroups e coverpoints.

Alguns conceitos importantes:

Criando e Configurando um covergroup🔗

A forma básica de criar um covergroup em SystemVerilogIntrodução ao SystemVerilog: História e EvoluçãoIntrodução ao SystemVerilog: História e EvoluçãoDescubra a trajetória do SystemVerilog, sua origem a partir do Verilog, e os marcos que transformaram a verificação de hardware na indústria digital. é utilizando a sintaxe:

covergroup nome_covergroup @(clock_or_event);
  // Declarações de coverpoints
endgroup

1. nome_covergroup: Identificador único usado para instanciar o covergroup.

2. @(clock_or_event): Define em qual evento ou sinal de clockOsciladores e Relógios Digitais: Geração e Uso de Sinais de SincronismoOsciladores e Relógios Digitais: Geração e Uso de Sinais de SincronismoDescubra o papel essencial dos osciladores e sinais de clock na sincronização e funcionamento de circuitos digitais modernos. o covergroup fará a amostragem (sampling).

Exemplo de covergroup simples

module exemplo_cover;
  logic clock;
  logic [3:0] data;
  // Definição do covergroup
  covergroup data_cg @(posedge clock);
    coverpoint data {
      bins valor_baixo = {0, 1, 2};
      bins valor_medio = {3, 4, 5, 6, 7};
      bins valor_alto  = {8, 9, 10, 11, 12, 13, 14, 15};
    }
  endgroup
  // Instanciando o covergroup
  data_cg data_cg_inst = new();
  always #5 clock = ~clock; // Gera clock
  initial begin
    clock = 0;
    repeat (20) begin
      #10 data = $urandom_range(0, 15);
    end
    #20 $finish;
  end
endmodule

No exemplo acima:

Trabalhando com Opções de Cobertura🔗

Para definir metas e pesos na análise de cobertura, utilizamos opções dentro de covergroups e coverpoints. Alguns atributos comuns:

OpçãoDescrição
option.goalPercentual de cobertura que desejamos atingir para determinado coverpoint ou bins.
option.weightDefine a relevância de um coverpoint ou cross coverage em relação ao cálculo global.
option.commentAdiciona anotações ou descrições textuais para facilitar o entendimento do relatório.
option.per_instanceControla se será gerada cobertura separada por instância ou combinada.

Definindo Metas de Cobertura

Para customizar a meta de cobertura de um coverpoint, podemos fazer:

covergroup data_cg @(posedge clock);
  coverpoint data {
    option.goal = 90; // Exigimos 90% de cobertura neste coverpoint
    bins valor_baixo = {0, 1, 2};
    bins valor_medio = {3, 4, 5, 6, 7};
    bins valor_alto  = {8, 9, 10, 11, 12, 13, 14, 15};
  }
endgroup

Essa opção option.goal = 90 indica que desejamos atingir pelo menos 90% de cobertura para as faixas definidas nesse coverpoint.

Definindo Pesos de Cobertura

Às vezes, nem todos os coverpoints e cross coverages têm a mesma importância. Podemos atribuir pesos diferentes para refletir prioridades:

covergroup data_cg @(posedge clock);
  coverpoint data {
    option.goal   = 95;  // Meta de 95% de cobertura
    option.weight = 2;   // Dobra a relevância deste coverpoint na cobertura total
    bins valor_baixo = {0, 1, 2};
    bins valor_medio = {3, 4, 5, 6, 7};
    bins valor_alto  = {8, 9, 10, 11, 12, 13, 14, 15};
  }
endgroup

No exemplo, option.weight = 2 indica que esse coverpoint tem duas vezes mais impacto no cálculo global de cobertura do que os demais.

Ajustando Sampling e Filtros🔗

Evento de Amostragem (Sampling)

O sampling controla em qual evento (relacionado a clock ou qualquer outro sinal) a verificaçãoIntrodução ao SystemVerilog: História e EvoluçãoIntrodução ao SystemVerilog: História e EvoluçãoDescubra a trajetória do SystemVerilog, sua origem a partir do Verilog, e os marcos que transformaram a verificação de hardware na indústria digital. de cobertura será feita:

covergroup sample_cg @(negedge clock); // Amostra na borda de descida
  // ...
endgroup

Também é possível definir sampling explícito por meio de métodoMétodos e Sobrecarga: Técnicas para Maior FlexibilidadeMétodos e Sobrecarga: Técnicas para Maior FlexibilidadeDescubra como métodos, tasks, functions e sobrecarga em SystemVerilog otimizam a programação orientada a objetos com exemplos práticos e dicas de boas práticas.:

covergroup manual_cg;
  // ...
endgroup
initial begin
  manual_cg mcg = new();
  // Dispara a coleta de cobertura sob condição específica
  if (condicao_especial)
    mcg.sample();
end

Esse tipo de controle manual permite coletar cobertura apenas em determinados momentos ou condições, tornando a análise ainda mais personalizada.

Usando Bins Específicos e Exclusões

Para cenários em que certos valores não são relevantes ou queremos isolar casos especiais, podemos excluir bins ou usar illegal_bins:

coverpoint data {
  bins normal_values = {1, 2, 3, 4, 5};
  bins special_value = {10};
  illegal_bins invalid_values = {0, 15}; // Não queremos cobrir valores 0 e 15
}

Com isso, evitamos que valores irrelevantes afetem negativamente as métricas e focamos naquilo que realmente importa no design.

Cross Coverage: Métricas Multidimensionais🔗

Quando o comportamento de um sinal depende de outro, ou quando precisamos analisar a combinação de valores, utilizamos cross coverage. Essa prática é especialmente útil para verificar cenários em que data e outro sinal (por exemplo, enable) formam condições conjuntas:

covergroup cross_example @(posedge clock);
  coverpoint data {
    bins low  = {0, 1, 2};
    bins high = {3, 4, 5, 6, 7};
  }
  coverpoint enable {
    bins disabled = {0};
    bins enabled  = {1};
  }
  cross data, enable {
    option.goal   = 100;
    option.weight = 3;
  }
endgroup

Neste exemplo, estamos declarando um cross entre data e enable para verificar se todas as combinações (valores de data em conjunto com o estado de enable) foram exercitadas ao longo da simulaçãoSimulação e Depuração: Ferramentas e Dicas PráticasSimulação e Depuração: Ferramentas e Dicas PráticasAprenda técnicas de simulação e depuração em SystemVerilog, utilizando ferramentas, waveforms, asserts e logs para garantir designs confiáveis.. Aqui, option.goal foi definido em 100% para garantir total cobertura dessas combinações, e option.weight = 3 indica alta prioridade.

Exemplificando uma Configuração Completa🔗

A seguir, um exemplo completo que ilustra diversos aspectos de configuração de métricas de cobertura em um mesmo covergroup:

module test_coverage;
  logic clock, reset;
  logic [3:0] addr;
  logic       rw_flag;
  // Covergroup completo para ilustrar várias opções
  covergroup mem_access_cg @(posedge clock);
    coverpoint addr {
      option.goal   = 90;
      option.weight = 2;
      bins low_range     = {0,1,2,3,4};
      bins high_range    = {5,6,7,8,9,10,11,12,13,14,15};
      illegal_bins reset_conflict = {0} iff (reset == 1);
      // Caso de exemplo onde não queremos cobrir addr=0 se reset está ativo
    }
    coverpoint rw_flag {
      option.goal = 100;
      bins read  = {0};
      bins write = {1};
    }
    // Cross coverage entre addr e rw_flag
    cross addr, rw_flag {
      option.goal   = 95;
      option.weight = 1;
      option.comment = "Verificando todas as combinações de addr e rw_flag";
    }
  endgroup
  // Cria instância do covergroup
  mem_access_cg mem_cg_inst = new();
  // Geração de clock
  always #5 clock = ~clock;
  initial begin
    clock = 0;
    reset = 1;
    #10 reset = 0; // Desativa reset
    repeat (20) begin
      #10 addr = $urandom_range(0, 15);
           rw_flag = $urandom_range(0, 1);
    end
    #50 $finish;
  end
endmodule

Observações:

1. Definimos coverpoints para addr e rw_flag, cada um com opções de meta e peso específicas.

2. Inserimos bins diferenciados para valores baixos e altos de addr, além de um illegal_bins que ignora addr = 0 quando reset está ativo.

3. O cross entre addr e rw_flag possui option.goal = 95 e um comentário adicional para documentar o objetivo.

Conclusão🔗

A configuração de métricas de cobertura em SystemVerilogIntrodução ao SystemVerilog: História e EvoluçãoIntrodução ao SystemVerilog: História e EvoluçãoDescubra a trajetória do SystemVerilog, sua origem a partir do Verilog, e os marcos que transformaram a verificação de hardware na indústria digital. possibilita uma verificação intensa e detalhada do design, identificando rapidamente lacunas nos testes. Ao combinar:

  • Criação adequada de covergroups
  • Definição de coverpoints e bins específicos
  • Ajuste de metas (option.goal)
  • Ajuste de pesos (option.weight)
  • Uso de illegal_bins e cross coverage
…você garante que os testes abranjam as diversas combinações e cenários funcionais importantes, de forma direcionada e eficiente. O conhecimento desses recursos é fundamental para quem deseja realizar uma verificação robusta, auxiliando na identificação precoce de comportamentos indesejados no hardware.

Esperamos que este tutorial tenha esclarecido como configurar as métricas de cobertura em SystemVerilogIntrodução ao SystemVerilog: História e EvoluçãoIntrodução ao SystemVerilog: História e EvoluçãoDescubra a trajetória do SystemVerilog, sua origem a partir do Verilog, e os marcos que transformaram a verificação de hardware na indústria digital. e sirva de base para personalizações mais avançadas no seu fluxo de verificaçãoIntrodução ao SystemVerilog: História e EvoluçãoIntrodução ao SystemVerilog: História e EvoluçãoDescubra a trajetória do SystemVerilog, sua origem a partir do Verilog, e os marcos que transformaram a verificação de hardware na indústria digital.. Assim, gradativamente, você pode elevar a qualidade das suas entregas em projetos de design eletrônico.

Autor: Marcelo V. Souza - Engenheiro de Sistemas e Entusiasta em IoT e Desenvolvimento de Software, com foco em inovação tecnológica.

Referências🔗

  • Accellera – Organismo responsável pelos padrões e avanços na área de design e verificação, com informações que podem reforçar boas práticas em cobertura: www.accellera.org
  • ASIC World – Oferece tutoriais e exemplos de SystemVerilog, que podem ajudar a contextualizar a aplicação de métricas de cobertura: www.asic-world.com/systemverilog/
  • ChipVerify – Tutorial abrangente sobre SystemVerilog, com conteúdos que podem complementar a explicação sobre métricas de cobertura: www.chipverify.com/systemverilog/systemverilog-tutorial
  • IEEE Standard – Fonte oficial para padrões que regem a linguagem SystemVerilog, servindo de base para a implementação correta das construções de cobertura: www.ieee.org
  • SystemVerilog.io – Recurso geral para aprendizado de SystemVerilog, útil para aprofundar conceitos utilizados na configuração de covergroups e coverpoints: www.systemverilog.io

Compartilhar artigo

Artigos Relacionados