Verilog'da "Operatör" Ne Demek
Operatörler sinyal taşıyan ifadeleri alır ve yeni sinyal taşıyan ifadeler üretir. a + b donanımdır - sentezleyici onu bir adder'a dönüştürür. a == b donanımdır - bir karşılaştırıcı kurar. Bunların hiçbiri "çalışan kod" değildir; hepsi "operatörün tanımladığı devreler"dir.
Tam operatör menüsü ezberleyecek kadar küçüktür. Bu doc aritmetik, karşılaştırma, mantıksal ve koşullu operatörleri kapsar. Bitwise and Reduction, doğrudan yazılım karşılığı olmayan bit düzeyi operatörlerini kapsar.
Aritmetik: + - * / %
Bilmeniz gereken üç şey:
- Bölme integer bölmedir.
7/2,3.5değil3'tür. Verilog'un bir float tipi yoktur (eh,realvar ama o yalnızca simülasyon). - Bölme ve modulo donanımda pahalıdır. Bir
/4iyidir (sentezleyici onu bir sağ shift'e dönüştürür), ama çalışma zamanı değişkenniçin bir/nneredeyse hiç istemediğin çok döngülü bir divider kurar. - Taşma sarar. N bit aşan iki N bitlik unsigned değerin toplanması N bite truncate olur. Carry'yi yakalamak istiyorsan, sonucu bir bit daha geniş tanımla:
wire [7:0] a, b;
wire [8:0] sum = a + b; // 9 bitlik sum carry out'u yakalar
Karşılaştırma: == != < > <= >=
Altı karşılaştırma operatörü de tek bitlik bir sonuç döndürür: doğruysa 1, yanlışsa 0, herhangi bir operand'da x veya z bit varsa x. x/z durumunu işlemek için, X and Z Values bölümünde kapsanan === ve !== (case-equality operatörleri) için uzan.
Burada <= karşılaştırma operatörüdür (küçük eşit). Aynı karakterler bir prosedürel blokta non-blocking atama da demektir (q <= d). Bağlam bunları ayırır: bir ifade içinde karşılaştırmadır; atanan bir değerin solunda atamadır. Örtüşme kafa karıştırıcıdır ama parser için belirsizdir.
Mantıksal: && || !
Mantıksal operatörler operandlarını boolean olarak ele alır (sıfır olmayan her şey doğrudur, sıfır yanlıştır) ve tek bitlik bir sonuç üretir:
İçselleştirilecek kritik ayrım: mantıksal &&, bitwise & değildir.
4'b1100 && 4'b0011 // 1 (ikisi de sıfır olmayan, mantıksal AND doğru)
4'b1100 & 4'b0011 // 4'b0000 (ikisinde de hiçbir bit pozisyonu 1 değil)
|| vs | için aynı. if koşullarında ve ?: yüklemlerinde mantıksal kullan; her bit pozisyonunun bağımsız olarak AND/OR olmasını istediğinde bitwise kullan.
&& ve ||, C anlamında short-circuit'tir: sağ taraf, sonuç sol tarafa göre zaten belirlenmişse değerlendirilmez. Bu, pointer'ları veya fonksiyon çağrılarını kontrol eden testbench'ler için önemlidir; her şeyin zaten paralel olduğu sentezlenebilir RTL için nadiren önemlidir.
Koşullu Operatör: ?:
Ternary, mux ve koşullu ifadeler kurmak için en iyi arkadaşındır:
cond ? a : b kalıbı donanımda 1 bitlik-seçimli 2-to-1 bir multiplexer'dır. Bunları zincirlemek 3 ve 4 yollu seçimler için iyidir, ama ondan sonra bir case ifadesi ((Case Statement bölümünde kapsanır) dramatik olarak daha okunaklıdır.
?: operatörü ayrıca yalnızca bazen override ettiğin bir register'a varsayılan bir değer vermenin standart yoludur:
next_value = update ? new_data : next_value;
Genişlik Kuralları: Başlangıç Tuzağı
Aritmetik operatörler için Verilog'un genişlik kuralları kötü şöhretli derecede sürprizlidir. Kısa versiyon:
- Sonucun genişliği girişlerin genişliklerinin maksimumudur.
- Sonuç daha geniş bir şeye atanırsa, sıfır ile genişletilir (signed ise sign-extended).
- Ara hesaplamaların genişliği de sonuç genişliğidir, bu da taşmanın ara hesaplamada gerçekleştiği anlamına gelir.
İlk çarpma taşar çünkü operand genişlikleri her ikisi de 8 bittir, bu yüzden sonuç genişliği 8 bittir ve 40000 sığmaz. İkincisi çalışır çünkü çarpmadan önce a'yı açıkça genişlettik.
Düzeltme satır teknikleri:
- Sıfır ile genişletmek için concatenation operatörü
{8'b0, a}kullan. - Yorumlamayı etkilemek için
$unsigned(a)veya$signed(a)kullan. - Şüphe duyduğunda ara ifadeleri daha geniş genişliklere cast et.
Operatör Önceliği
Tabloyu ezberlemeyeceksin, ama birkaç kurala dayanacaksın:
*,/,%,+,-'den daha sıkı bağlar.- Karşılaştırma, mantıksal'dan (
&&,||) daha sıkı bağlar. - Koşullu operatör
?:çok düşük önceliğe sahiptir - genellikle daha büyük ifadelerde dallarının etrafında parens gerekir. - Şüphe ettiğinde, parantezle. Simülatör karakter başına ücret almıyor.
out = (mode == 2'd0) ? a + b : a - b; // parens ile daha net
Sırada Ne Var
Yazılım kuzeni gibi görünen her operatörü kapsadın. Bir sonraki doc - Bitwise and Reduction - doğrudan yazılım karşılığı olmayan operatörleri ele alır: bit başına bitwise AND/OR/XOR, artı bütün bir vektörü tek bir bite indiren reduction formları.
Sıkça Sorulan Sorular
Verilog hangi operatörleri destekler?
Verilog'un dört geniş operatör ailesi vardır: aritmetik (+, -, *, /, %), karşılaştırma (==, !=, <, >, <=, >=), mantıksal (&&, ||, !) ve bitwise/reduction (&, |, ^, ~, ~&, ~|, ~^). Artı shift operatörleri (<<, >>, <<<, >>>), concatenation {}, replication {N{...}} ve koşullu ?:.
Verilog'da && ile & arasındaki fark nedir?
&& mantıksal AND'dir - her operandı boolean (sıfır veya sıfır olmayan) olarak işler ve 1 bitlik bir sonuç döndürür. & bitwise AND'dir - bitleri pozisyon pozisyon eşleştirir. 4'b1100 && 4'b0011 ifadesi 1'dir (ikisi de sıfır olmayan); 4'b1100 & 4'b0011 ifadesi 4'b0000'dır. Koşullarda &&, bit düzeyi işlemler için & kullan.
Verilog'da bölme nasıl çalışır?
Integer bölme - kesirli kısım atılır. 7 / 2, 3.5 değil 3'tür. % operatörü kalanı verir: 7 % 2 ifadesi 1'dir. Sıfıra bölme simülasyonda x (bilinmeyen) üretir. Her iki operatör de teknik olarak sentezlenebilir ama FPGA'larda ve ASIC'lerde çok büyük, yavaş donanım üretir - bölen 2'nin kuvveti olmadıkça sentezlenebilir path'lerde kaçın.
Verilog'da koşullu operatör nedir?
?:, C'den kopyalanan ternary veya koşullu operatördür. cond ? a : b, cond doğruysa (sıfır olmayan) a'ya, aksi halde b'ye değerlendirilir. Multiplexer benzeri mantık için en çok kullanılan yapıdır: out = sel ? in1 : in0, 2-to-1 bir mux kurar. ?: zincirleri daha geniş mux'lar kurar, ama iki girişten sonra case genellikle daha nettir.