A anatomia de um literal sized
Um literal Verilog tem até três partes:
8'b1010_1100
│ │ │
│ │ └─ dígitos na base escolhida
│ └─── especificador de base: b (binário), h (hex), d (decimal), o (octal)
└────── largura em bits (decimal)
Lendo da esquerda para a direita: "um valor de 8 bits, escrito em binário, com os dígitos 10101100". Isso é 172 em decimal, 0xAC em hex, os mesmos bits independente de como você escreva. A largura diz ao compilador exatamente quantos bits alocar; a base diz como interpretar os dígitos.
Underscores são separadores visuais. 32'b1010_1100_0011_0101 é o mesmo que 32'b1010110000110101. Use-os.
As quatro bases
Hex (h) é o padrão para qualquer coisa mais larga que 4 bits. Binário (b) é o padrão quando você quer ler padrões de bit diretamente. Decimal (d) é para contagens com significado humano. Octal (o) existe mas você quase nunca verá.
Dígitos hex são case-insensitive: 8'hAB e 8'hab são idênticos.
O que acontece quando o valor não cabe?
Se seus dígitos não preencherem a largura declarada, Verilog zero-extende à esquerda:
8'b101 // equivalente a 8'b00000101 (= 5)
8'hF // equivalente a 8'h0F (= 15)
Se seus dígitos excedem a largura declarada, Verilog trunca os bits altos com um aviso:
4'hFF // trunca para 4'hF, simulador avisa
4'b10000 // trunca para 4'b0000
O aviso é seu amigo. Não o suprima.
Sized vs Unsized
Um literal sem largura:
'd10 // unsized, pega o tamanho padrão (≥32 bits)
10 // também unsized - sem base significa decimal
Literais unsized por padrão são 32 bits na maioria das ferramentas. Essa é a fonte de uma classe inteira de bugs:
reg [7:0] count;
if (count == -1) ... // -1 é unsized 32-bit; comparação fica estranha
A correção é escrever 8'hFF em vez de -1, ou 8'd255, ou {8{1'b1}}. Sempre dê tamanho a literais quando são usados em expressões específicas de largura.
O único lugar onde literais unsized estão bem é em contadores inteiros em loops for de testbench, onde o inteiro é largo o suficiente para nada surpreendente acontecer.
Literais signed
Por padrão, literais sized são unsigned:
8'd255 // unsigned 255
8'b1111_1111 // unsigned 255 - mesmo padrão de bit, apenas escrito diferente
Se você quer o literal interpretado como signed, adicione s depois do apóstrofo:
8'sd10 // signed 10
8'sb1111_1111 // signed -1 (complemento de dois)
A flag s importa para:
- Os operadores
<<<e>>>(shifts aritméticos) - eles fazem sign-extend de operandos signed. - Operadores de comparação em expressões mistas signed.
- As conversões
$signed/$unsigned.
Para a maioria da aritmética comum em sinais de barramento, você vai deixar o s de fora.
Literais numéricos com X e Z
Um dígito literal pode ser x (desconhecido) ou z (alta impedância):
8'bx é abreviação para "todos os 8 bits desconhecidos" - o valor é propagado para preencher a largura declarada. Dígitos x são comuns em casos default de máquinas de estado e em inicialização. Cobrimos a semântica em X e Z Values.
Onde literais sized aparecem na prática
Uma vez que você começa a escrever modules reais, literais sized aparecem em todos os lugares:
// Larguras de barramento
input wire [31:0] addr;
wire [31:0] zero = 32'h0;
wire [31:0] all_ones = 32'hFFFF_FFFF;
// Codificações de estado
localparam IDLE = 3'd0;
localparam BUSY = 3'd1;
localparam DONE = 3'd2;
// Máscaras
wire is_msb_set = data & 32'h8000_0000;
// Comparações
if (counter == 8'd255) ...
// Valores de reset
always @(posedge clk) begin
if (reset) data_out <= 8'd0;
else data_out <= data_in;
end
O padrão é consistente: escreva a largura, escreva a base, escreva os dígitos. Cada literal que você usa tem a mesma forma.
Um test drive
Você agora tem tudo que precisa para escrever qualquer constante que um module Verilog poderia querer. A última peça da história de tipos de dado é o que acontece quando um sinal não é um 0 ou 1 limpo - os valores x e z.
Perguntas frequentes
O que 8'b1010 significa em Verilog?
É um literal binário com tamanho: um valor de 8 bits cuja representação binária é 00001010. O número antes do apóstrofo é a largura em bits; a letra depois do apóstrofo é a base (b binário, h hex, d decimal, o octal); os dígitos depois são o valor. O literal é preenchido com zeros à esquerda se os dígitos não preencherem a largura.
Qual a diferença entre números sized e unsized em Verilog?
Um literal sized como 8'd10 tem exatamente 8 bits de largura. Um literal unsized como 'd10 ou simplesmente 10 por padrão é 32 bits, o que geralmente é demais. Misturar literais unsized em expressões específicas de largura causa bugs sutis - prefira literais sized em todos os lugares fora de código de teste descartável.
Como escrevo um número hex em Verilog?
Use o especificador de base 'h: 8'hFF é um valor de 8 bits igual a 255. Dígitos hex são case-insensitive; 8'hff e 8'hFF são idênticos. Você pode agrupar dígitos com underscores para legibilidade: 32'hDEAD_BEEF. Os underscores são ignorados pelo parser.
Como underscores funcionam em números Verilog?
Underscores são separadores visuais que o parser ignora. 32'b1010_1100_0011_0101 é exatamente o mesmo valor que 32'b1010110000110101 mas muito mais fácil de ler. O primeiro caractere depois do prefixo de base não pode ser um underscore, mas você pode colocá-los em qualquer outro lugar na string de dígitos.
Como escrevo um número signed em Verilog?
Adicione s depois do apóstrofo: 8'sd10 é um decimal signed 10 de 8 bits, e 8'sb1111_1111 é signed -1. Por padrão, literais sized são unsigned; o modificador s inverte isso. A maioria da aritmética usa operandos unsigned - recorra a signed só quando você genuinamente precisa que valores negativos se propaguem por <, >>> e operadores similares.