Menu

Verilog Vector'lar ve Array'ler: Çok Bitli Sinyaller Açıklaması

[7:0] ile çok bitli sinyaller nasıl tanımlanır, dilimlenir, birleştirilir ve packed bir vector ile bir memory array arasındaki fark.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

Bir Wire vs Birçok

Şimdiye kadar gördüğümüz her sinyal bir bit genişliğindeydi. Gerçek tasarımlar neredeyse hiç böyle görünmez - adresler 16 veya 32 bit, veri bus'ları 8 veya 64, RGB piksel'leri 24'tür. Verilog sana herhangi bir sinyali çok bitli yapmak için tek bir mekanizma verir: köşeli parantezlere bir aralık ekle.

wire [7:0] data;       // 8 bitlik wire, bit 7 MSB, bit 0 LSB
reg  [15:0] address;   // 16 bitlik reg
output reg [31:0] result; // 32 bitlik modül çıkışı

Parantezler arasındaki sayılar en anlamlı ve en az anlamlı bitlerin bit pozisyonları'dır. [7:0], "bu sinyal 7'den 0'a numaralandırılmış bitlere sahip" demektir, bu da toplam 8 bittir. İlk sayı yüksek indeks. İkincisi düşük.

Bazen [0:7] göreceksin - aynı sayıda bit, dilimleme amacıyla zıt endianness. [high:low] formu ezici endüstri geleneğidir; aksini yapmak için güçlü bir nedenin olmadıkça buna bağlı kal.

Çalışılmış Bir Örnek: 8-Bit Adder

Her +, iki 8 bitlik vector'ı ekler ve 9 bitlik bir sonuç üretir. 8'd10 gibi sayı literal'leri "10'un 8 bit genişliğinde decimal değeri" der - bunları Number Literals bölümünde kapsayacağız.

Dilimleme: Bitleri Seçme

Bir vector'ın olduğunda, bireysel bitleri veya bitişik aralıkları çekebilirsin:

Testbench'in force satırına takılma - dilimlemeyi göstermek için sadece bir değer enjekte etmenin bir yoluna ihtiyacımız vardı. İlginç kısım dilimlerin kendileridir.

Birkaç kural:

  • Dilim yönü tanımlamayla eşleşmelidir. [7:0] tanımladıysan, [high:low] ile dilimle. Yönü tersine çevirmek bir sözdizimi hatasıdır.
  • Aralık dışında dilimleme simülasyonda x (bilinmeyen) üretir. Sentez aracı uyarabilir veya hata verebilir.
  • Bit seçimi yazdığın indeks üzerinde sıfır tabanlıdır - data[0], 0 adlı bittir, ki bu (bir [7:0] tanımlama için) LSB'dir.

Değişken-Baz Dilimleri: +: ve -:

Yaygın bir ihtiyaç: "bana bit N'den başlayarak 8 bit ver". data[N+7:N]'i doğrudan yazamazsın çünkü Verilog aralığın her iki ucunun da sabit olmasını gerektirir. Bunu çözen sözdizimi:

data[base +: width]   // `base`'ten başlayarak YUKARI giden width bit
data[base -: width]   // `base`'ten başlayarak AŞAĞI giden width bit

Genişlik sabittir (her seferinde 8 bit seçiyoruz) ama baz bir çalışma zamanı ifadesi olabilir. Bu, byte adreslenebilir memory'ler, shift register tap'leri vb. için ihtiyacın olan tam şeydir.

Array'ler: Vector'ların Bir Adım Ötesi

Bir vector tek bir çok bitli sinyaldir. Bir array, bağımsız olarak indekslenen bir vector koleksiyonudur:

reg [31:0] mem [0:1023];

Bu tanım iki aralıktır ve iki aralık farklı şeyler ifade eder:

  • [31:0], packed boyut'tur - her bireysel kelimenin genişliği.
  • [0:1023], unpacked boyut'tur - kaç kelime olduğu.

Yani mem, 1024 ayrı 32 bitlik register'dır. Birine tek bir indeksle erişirsin:

mem[5] = 32'hCAFE_BABE;       // kelime 5'i yaz
data   = mem[address];        // `address`'teki kelimeyi oku

Bu kareleri tutan küçük bir memory'dir. Gerçek tasarımlar register file'lar, lookup table'lar, FIFO'lar ve tek bir vector'dan büyük herhangi bir on-chip depolama için aynı kalıbı kullanır.

Packed vs Unpacked: Neden Önemli

Packed ve unpacked boyutlar arasındaki bölünme her yerde ortaya çıkar. Hangisinin hangisi olduğunu bilmek bir sürü debug'tan tasarruf sağlar:

  • Packed bir vector tek bir sinyaldir. Tümünü bir sayı olarak ele alabilirsin: data + 1 çalışır, data == 32'h0 çalışır, data[7:0] çalışır.
  • Unpacked bir array birçok sinyaldir. Tümünü bir sayı olarak ele alamazsın: mem + 1 bir sözdizimi hatasıdır. Önce belirli bir kelimeyi seçmelisin.

Birden çok packed boyut da yasaldır:

reg [3:0][7:0] regs;   // 32 bitlik bir sinyale paketlenmiş 4 byte

regs[0], bir byte'tır (alt byte). regs bütün olarak 32 bittir. SystemVerilog bunu yoğun olarak kullanır.

Birden çok unpacked boyut bir 2D memory oluşturur:

reg [31:0] frame [0:479][0:639];  // 32 bitlik piksel'lerin 480x640'ı

Tek bir piksel'e frame[y][x] ile erişirsin. HDL'de bir image buffer böyle görünür.

Sırada Ne Var

Artık ihtiyacın olan herhangi bir genişlikte sinyali tanımlayıp manipüle edebilirsin. Bir sonraki doc - Parameters - aynı modülün bir instance'da 8 bit, başka bir instance'da 32 bit çalışması için bu genişlikleri konfigüre edilebilir yapmayı gösterir. Sonra literal sayı yazma kurallarına (8'b1010_1100, 32'hDEAD_BEEF) ve bir şey sürülmediğinde ortaya çıkan x/z değerlerine geçeceğiz.

Sıkça Sorulan Sorular

Verilog'da vector nedir?

Bir vector, çok bitli bir sinyaldir. Bir wire'a veya reg'e bir aralık ekleyerek tanımlarsın: wire [7:0] data, 8 bitlik bir wire'dır. Parantezler arasındaki sayılar bit pozisyonlarıdır - bu durumda bit 7 en anlamlıdır ve bit 0 en az anlamlıdır. Bireysel bitleri (data[3]) veya bitişik aralıkları (data[7:4]) dilimleyebilirsin.

Verilog'da [7:0] ne anlama gelir?

[7:0], bit 7'den bit 0'a dahil olan bir aralığı tanımlar - en anlamlı bit olarak bit 7 ile 8 bitlik bir sinyal. İlk sayı yüksek indeks, ikincisi düşüktür. Little-endian indeksleme için [0:7] de yazabilirsin, ama [high:low] formu endüstri kodunda çok daha yaygın gelenektir.

Verilog'da bitler nasıl dilimlenir?

Parantez indeksleme kullan. data[3], tek bir bit seçer. data[7:4], üst dört biti 4 bitlik bir vector olarak seçer. Dilim, tanımlamayla aynı yönde olmalıdır - [7:0] tanımladıysan, [high:low] ile dilimle. SystemVerilog ayrıca sabit genişlikteki değişken-baz dilimleri için data[3 +: 4] ekler.

Verilog'da packed ve unpacked array arasındaki fark nedir?

Bir packed array, tek bir bitişik bus'tır - reg [31:0] word, bir 32 bitlik sinyaldir. Bir unpacked array (veya 'memory'), bağımsız kelimelerin bir koleksiyonudur - reg [31:0] mem [0:1023], 1024 ayrı 32 bitlik register'dır. Bir unpacked array'in tam bir kelimesini okuyabilir veya yazabilirsin ama tamamı üzerinde tek bir sinyal olarak işlem yapamazsın.

Verilog'da bir memory nasıl tanımlanır?

reg [31:0] mem [0:1023];, her biri 32 bit genişliğinde 1024 girişlik bir memory tanımlar. İlk parantez seti kelime genişliği'dir (packed); ikincisi kelime sayısı'dır (unpacked). Bir girişe mem[address] ile eriş ve SystemVerilog-2005 indeksleme etkinleştirildiğinde o girişin bir dilimini mem[address][7:0] ile okuyabilir veya yazabilirsin.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA