Entendendo Escalares e Vetores Verilog: Bits, Registradores e Tipos de Net
Verilog precisa representar bits individuais assim como grupos de bits. Por exemplo, um elemento sequencial de bit único é um flip-flop. No entanto, um elemento sequencial de 16-bit é um registrador que pode guardar 16 bits. Para este propósito, Verilog tem escalares e vetores nets e variáveis.
Escalar e Vetor
Uma declaração de net ou reg sem especificação de range é considerada 1-bit de largura e é um escalar. Se um range for especificado, então a net ou reg torna-se uma entidade multibit conhecida como vetor.
wire o_nor; // single bit scalar net
wire [7:0] o_flop; // 8-bit vector net
reg parity; // single bit scalar variable
reg [31:0] addr; // 32 bit vector variable to store address
O range dá a capacidade de endereçar bits individuais em um vetor. O bit mais significativo do vetor deve ser especificado como o valor left-hand no range enquanto o bit menos significativo deve ser especificado à direita.
wire [msb:lsb] name;
integer my_msb;
wire [15:0] priority; // msb = 15, lsb = 0
wire [my_msb: 2] prior; // illegal
Uma net de 16 bits chamada priority será criada no exemplo acima. Note que o msb e lsb devem ser uma expressão constante e não podem ser substituídos por uma variável. Mas podem ser qualquer valor inteiro - positivo, negativo ou zero; e o valor lsb pode ser maior que, igual a ou menor que o valor msb.
Bit-selects
Qualquer bit em uma variável vetorizada pode ser individualmente selecionado e atribuído um novo valor como mostrado abaixo. Isso é chamado de bit-select. Se o bit-select estiver fora dos limites ou o bit-select for x ou z, então o valor retornado será x.
reg [7:0] addr; // 8-bit reg variable [7, 6, 5, 4, 3, 2, 1, 0]
addr [0] = 1; // assign 1 to bit 0 of addr
addr [3] = 0; // assign 0 to bit 3 of addr
addr [8] = 1; // illegal : bit8 does not exist in addr
Part-selects
Um range de bits contíguos pode ser selecionado e é conhecido como part-select. Existem dois tipos de part-selects, um com part-select constante e outro com part-select indexado.
reg [31:0] addr;
addr [23:16] = 8'h23; // bits 23 to 16 will be replaced by the new value 'h23 -> constant part-select
Ter um part-select variável permite que seja usado efetivamente em loops para selecionar partes do vetor. Embora o bit inicial possa variar, a largura tem que ser constante.
[ +: ] // part-select increments from start-bit
[ -: ] // part-select decrements from start-bit
module des;
reg [31:0] data;
int i;
initial begin
data = 32'hFACE_CAFE;
for (i = 0; i < 4; i++) begin
$display ("data[8*%0d +: 8] = 0x%0h", i, data[8*i +: 8]);
end
$display ("data[7:0] = 0x%0h", data[7:0]);
$display ("data[15:8] = 0x%0h", data[15:8]);
$display ("data[23:16] = 0x%0h", data[23:16]);
$display ("data[31:24] = 0x%0h", data[31:24]);
end
endmodule
Erros Comuns
module tb;
reg [15:0] data;
initial begin
$display ("data[0:9] = 0x%0h", data[0:9]); // Error : Reversed part-select index expression ordering
end
endmodule
Verilog
- Domine o Verilog: Tutorial Completo para Projeto de Circuitos Digitais
- Dominando Concatenação Verilog: Guia Prático
- Entendendo Atribuições em Verilog: Tipos, Sintaxe e Boas Práticas
- Verilog Blocking vs Non-Blocking: Diferenças Essenciais Explicadas
- Dominando Funções em Verilog para Design RTL Eficiente
- Entendendo Tasks em Verilog: Funções vs Tasks, Sintaxe e Uso
- Entendendo Atrasos Inter- e Intra-Atribuição em Verilog
- Gerador de Clock Verilog: Guia de Design e Implementação
- Dominando Funções Matemáticas do Verilog para Design de Hardware Eficiente
- Dominando $timeformat do Verilog: Precisão e Controle de Exibição