Estruturas e Uniões em SystemVerilog: Guia Prático

As estruturas (structs) e uniões (unions) 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. são recursos fundamentais para organizar dados de forma clara e eficiente. Elas permitem agrupar múltiplos elementos em um único tipo composto, facilitando a leitura do código, a manipulação de dados complexos e o transporte de informações em blocos de design ou em testbenches. Neste tutorial, veremos:

O que é uma Estrutura (struct)🔗

Uma estrutura agrupa múltiplos campos em um único tipo, permitindo tratar o conjunto de variáveisMapas de Karnaugh: Otimização de Circuitos e Minimização de FunçõesMapas de Karnaugh: Otimização de Circuitos e Minimização de FunçõesDescubra como os Mapas de Karnaugh simplificam expressões lógicas, otimizando circuitos digitais e facilitando o projeto em eletrônica digital. como uma só entidade. Dessa forma, fica mais fácil ler e manipular esses campos dentro de um bloco de código.

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., existem dois tipos principais de estruturas:

1. Packed: Armazena os campos de modo contíguo em nível de bitsSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalAprenda conversões de sistemas numéricos em eletrônica digital. Descubra métodos para converter entre decimal, binário, octal e hexadecimal com exemplos., formando um único vetor binárioSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalAprenda conversões de sistemas numéricos em eletrônica digital. Descubra métodos para converter entre decimal, binário, octal e hexadecimal com exemplos..

2. Unpacked: Armazena os campos de forma mais flexível, permitindo uso de tipos variados e sem a necessidade de estarem próximos em nível de bitsSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalAprenda conversões de sistemas numéricos em eletrônica digital. Descubra métodos para converter entre decimal, binário, octal e hexadecimal com exemplos..

Sintaxe de uma Estrutura

A declaração de uma estrutura segue a sintaxe abaixo:

// Declaração de uma estrutura "unpacked"
typedef struct {
    logic [7:0]  campoA;
    int          campoB;
    logic        campoC;
} minha_estrutura_t;

No exemplo acima, minha_estrutura_t torna-se um novo tipo de dados que contém três campos:

Para utilizar esse tipo em uma variável, basta declarar:

minha_estrutura_t exemplo_var;
initial begin
    // Atribuição de valores
    exemplo_var.campoA = 8'hFF;
    exemplo_var.campoB = 42;
    exemplo_var.campoC = 1'b0;
end

Estruturas Empacotadas (Packed)

As estruturas empacotadas são úteis para agrupar sinais ou campos de bit que precisam ser tratados como um único vetor binárioSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalAprenda conversões de sistemas numéricos em eletrônica digital. Descubra métodos para converter entre decimal, binário, octal e hexadecimal com exemplos.. Cada campo dentro de uma packed struct deve ter um tamanho em bitsSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalAprenda conversões de sistemas numéricos em eletrônica digital. Descubra métodos para converter entre decimal, binário, octal e hexadecimal com exemplos. definido.

typedef struct packed {
    logic       sinal_flag;
    logic [3:0] nibble;
    logic [7:0] byte_data;
} packed_struct_t;

Neste caso, packed_struct_t é um vetor de 1 + 4 + 8 = 13 bitsSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalAprenda conversões de sistemas numéricos em eletrônica digital. Descubra métodos para converter entre decimal, binário, octal e hexadecimal com exemplos. no total. Toda a estrutura pode ser manipulada bit a bit ou como um único inteiro, facilitando conversões ou compartilhamentos em barramentos digitais.

packed_struct_t dados;
initial begin
    // Atribuição bit a bit
    dados = 13'b1_1010_11001010;
    // Acesso aos campos
    $display("Sinal Flag = %b", dados.sinal_flag);
    $display("Nibble     = %b", dados.nibble);
    $display("Byte data  = %h", dados.byte_data);
end

A packed struct é muito usada em protocolos de comunicação, registros de status e em situações onde é necessário mapear sinais diretamente em hardware.

Uniões (union)🔗

Uma união (union) é semelhante a uma estrutura, mas todos os campos compartilham o mesmo espaço de armazenamento em memória. Em outras palavrasIntrodução à Eletrônica Digital: Conceitos básicos: bits, bytes, palavras, sinais de clock e sua importânciaIntrodução à Eletrônica Digital: Conceitos básicos: bits, bytes, palavras, sinais de clock e sua importânciaDomine fundamentos da eletrônica digital: bits, bytes, palavras e clock que impulsionam o desempenho e eficiência de sistemas modernos., a união só tem tamanho suficiente para acomodar o maior de seus campos, e cada campo sobrepõe o outro na memória.

Quando usar uniões

As uniões são úteis quando se deseja reinterpretar os bits de um mesmo espaço de armazenamento de formas diferentes. Por exemplo, para converter um valor binário em um número inteiro ou vice-versa, sem precisar copiar os dados para variáveisMapas de Karnaugh: Otimização de Circuitos e Minimização de FunçõesMapas de Karnaugh: Otimização de Circuitos e Minimização de FunçõesDescubra como os Mapas de Karnaugh simplificam expressões lógicas, otimizando circuitos digitais e facilitando o projeto em eletrônica digital. diferentes.

Sintaxe de uma União

Assim como as estruturas, podemos ter uniões empacotadas (packed) ou desempacotadas (unpacked). A seguir, um exemplo de packed union:

typedef union packed {
    logic [15:0] all_bits;
    struct packed {
        logic [7:0] byte_hi;
        logic [7:0] byte_lo;
    } bytes;
} my_union_t;

Aqui, all_bits e bytesIntrodução à Eletrônica Digital: Conceitos básicos: bits, bytes, palavras, sinais de clock e sua importânciaIntrodução à Eletrônica Digital: Conceitos básicos: bits, bytes, palavras, sinais de clock e sua importânciaDomine fundamentos da eletrônica digital: bits, bytes, palavras e clock que impulsionam o desempenho e eficiência de sistemas modernos. ocupam o mesmo espaço de 16 bits. Tanto faz ler pela visão “all_bits” ou pela visão “bytes.byte_hi / bytesIntrodução à Eletrônica Digital: Conceitos básicos: bits, bytes, palavras, sinais de clock e sua importânciaIntrodução à Eletrônica Digital: Conceitos básicos: bits, bytes, palavras, sinais de clock e sua importânciaDomine fundamentos da eletrônica digital: bits, bytes, palavras e clock que impulsionam o desempenho e eficiência de sistemas modernos..byte_lo”: são interpretações diferentes de um mesmo dados.

Exemplo de uso:

my_union_t valor_teste;
initial begin
    // Atribuição via campo 'all_bits'
    valor_teste.all_bits = 16'hA5F0;
    // Leitura via campo 'bytes'
    $display("Byte inferior = %h", valor_teste.bytes.byte_lo);  // F0
    $display("Byte superior = %h", valor_teste.bytes.byte_hi);  // A5
end

Importante: Ao modificar qualquer campo da união, todos os outros campos são afetados, pois compartilham a mesma área de memória.

Comparando Estruturas e Uniões🔗

CaracterísticaStructUnion
ArmazenamentoCada campo tem seu próprio espaço de memória.Todos os campos compartilham o mesmo espaço.
Tamanho totalSoma dos tamanhos de todos os campos.Tamanho do maior campo (em bits ou bytes).
Acesso aos camposIndependentes (altera um, não afeta os demais).Compartilhados (altera um, afeta os demais).
Aplicação mais comumAgrupamento lógico de dados heterogêneos.Reinterpretação de dados em diferentes formatos.

Boas Práticas🔗

1. Escolha o tipo correto: Use struct quando precisar armazenar vários campos simultaneamente, e union quando desejar interpretar o mesmo conjunto de bitsSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalAprenda conversões de sistemas numéricos em eletrônica digital. Descubra métodos para converter entre decimal, binário, octal e hexadecimal com exemplos. de formas diferentes.

2. Prefira nomes claros para as variáveisMapas de Karnaugh: Otimização de Circuitos e Minimização de FunçõesMapas de Karnaugh: Otimização de Circuitos e Minimização de FunçõesDescubra como os Mapas de Karnaugh simplificam expressões lógicas, otimizando circuitos digitais e facilitando o projeto em eletrônica digital. e campos: facilita a leitura do código.

3. Empacotado vs. Desempacotado:

4. Cuide do alinhamento: em structs desempacotadas, os compiladores de simulação podem inserir espaçamentos para alinhar dados.

5. Comentários e documentação: descreva bem suas estruturas e uniões, explicando a intenção e o uso de cada campo.

Exemplo Prático🔗

Suponha que desejamos representar o status de um módulo com diversos indicadores:

typedef struct packed {
    logic [3:0] error_code;     // Códigos de erro
    logic       valid_data;     // Indica se dados são válidos
    logic [2:0] priority_level; // Prioridade do status
} status_struct_t;
module status_example;
    status_struct_t status_reg;
    initial begin
        // Configurando valores
        status_reg.error_code     = 4'b1001;
        status_reg.valid_data     = 1'b1;
        status_reg.priority_level = 3'b010;
        $display("Status atual = %0d bits = %b",
                  $bits(status_reg), status_reg);
    end
endmodule

Nesse packed struct, todos os campos somam 4 + 1 + 3 = 8 bitsSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalSistemas de Numeração e Conversão: Binário, Decimal, Octal e HexadecimalAprenda conversões de sistemas numéricos em eletrônica digital. Descubra métodos para converter entre decimal, binário, octal e hexadecimal com exemplos.. É uma forma compacta de representar diversos sinais relacionados em um único bloco.

Conclusão🔗

Estruturas (structs) e uniões (unions) 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. são ferramentas poderosas para quem deseja organizar dados complexos de forma clara e eficiente, seja para modelar blocos de hardware, seja para simplificar a lógica de verificação. Ao escolher entre struct e union, considere os requisitos de armazenamento, a forma de acesso aos campos e se os dados precisam ou não ser reinterpretados em diferentes formatos.

Com essas práticas, estudantes, engenheiros e entusiastas de linguagens de descrição e 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. lógica podem criar modelos mais legíveis, robustos e fáceis de manter.

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

Referências🔗

Compartilhar artigo