FPGA VHDL Adder Tasarımı

a) Full-Adder devresini VHDL kullanarak gerçekleyiniz.

Bunun için öncelikle bize bir Half-Adder bloğu gereklidir.

Bu Half-Adder bloğu kullanılarak Full-Adder oluşturursak,

Full-Adder devresi Testbench kodu:

fa_tb

b) Gerçeklemesini yaptığınız Full-Adder devresini kullanarak GENERATE statement yardımıyla iki tane 64 bitlik sayıyı toplayan bir adder fonksiyonunu VHDL kullanarak gerçekleyiniz. Gerçeklemesini yapacağınız adder devresinin girişleri A_IN,B_IN (64bit), çıkışları SUM_OUT (64 bit), CARRY_OUT (1 bit) olacaktır. (ADDER_64.vhd)

Testbench kodu:
Simulasyon sonucu

adder64_tb

FPGA üzerinde girdi-çıktı sinyalinin izlediği yol

ADDER_64

c) 64 bit’lik Full-Adder devresini, CARRY-LOOKAHEAD ADDER yöntemi ile gerçekleyiniz. (ADDER_CARRY_LOOKAHEAD.vhd)

d) 64 bit’lik Full-Adder devresini, CARRY-LOOKAHEAD ADDER yöntemi ile gerçekleyiniz. Multiplexer’ları gerçeklemek amacıyla WITH-SELECT statement kullanınız. (ADDER_CARRY_LOOKAHEAD_WS.vhd)

Full-Adder bloğu

Adder bloğu
FPGA üzerinde girdi-çıktı sinyalinin izlediği yol

ADDER_CLA_WS

e) 64 bit’lik Full-Adder devresini, CARRY-LOOKAHEAD ADDER yöntemi ile Virtex-7 serisi FPGA’ların CARRY4 makrosunu kullanarak gerçekleyiniz (ADDER_CARRY_LOOKAHEAD_MACRO.vhd). CARRY4 makrosunun nasıl instantiate edileceği ile bilgiyi aşağıdaki linkte bulabilirsiniz:
CARRY4 Makrosu

FPGA üzerinde girdi-çıktı sinyalinin izlediği yol

ADDER_MACRO

f) IEEE_STD_LOGIC_ARITH.ALL ve IEEE_STD_LOGIC_UNSIGNED.ALL paketleri ‘+’ operatörünün toplama yaparken kullanılmasına imkan vermektedir. Bu paketlerin vhdl kodları aşagıdaki klasörde yer alır.

<Xilinx kurulum klasörü>\Vivado\<2015.4>\data\vhdl\src\ieee\distributable

64 bitlik adder devresini + operatörünü kullanarak, girişleri INTEGER’a çevirerek gerçekleştiriniz. (ADDER_PLUS_SIGN.vhd)

Burada iki integer toplanacak, daha sonra STD_LOGIC’e geri çevirilecek. Değişkenleri STD_LOGIC’den INTEGER’a çevirmek, INTEGER’dan STD_LOGIC’e dödürmek için aşağıdaki fonksiyonlara ihtiyacınız olacaktır. Bunlar yukarıdaki kütüphanelerde tanımlıdır.

function CONV_STD_LOGIC_VECTOR(ARG: STD_ULOGIC; SIZE: INTEGER)
return STD_LOGIC_VECTOR

function CONV_INTEGER(ARG: STD_LOGIC_VECTOR) return INTEGER

Önemli Not: 64 bit’lik integer yoktur!

Full-Adder bloğu

Adder bloğu
FPGA üzerinde girdi-çıktı sinyalinin izlediği yol

ADDER_PLUS_SIGN

SONUÇ

XDC dosyası kullanılarak hesaplanan zamanlama değerleri nano saniye cinsinden aşağıdaki tabloda verilmiştir. Burada CLA kısaltması CARRY_LOOKAHEAD, ADDER_CLA_WS ise soruda d şıkkında istenen “with – select” statement’ı ile hazırlanan 64 bitlik Carry lookahead modülüdür. Tablo başlıklarında kullanılan kısaltmalar optimizasyon çeşitlerine karşılık gelmektedir. Burada “D” default değerlere, “P” performans altındaki optimizasyonlara, “F” ise Flow altındaki optimizasyonlara karşılık gelmektedir. Ek olarak, örneğin dördüncü kolonda kullanılan “D-P(Explore)” başlığı, sentez ayarlarının Default, Implement ayarlarının Performance(Runtime) optimizasyonu altında yapıldığını göstermektedir. Buna göre farklı optimizasyon çeşitleri ve varsayılan ayarlara göre yapılan sentez ve implementasyon sonucunda hesaplanan süre değerleri aşağıdaki gibidir. Burada farklı optimizasyon çeşitleri eğer süre olarak ciddi bir fark yaratmıyorsa, not edilmemiştir.

vhdl_adder_comparison

Burada en hızlı sonuç integer değişkenlerin kullanıldığı ADDER_PLUS_SIGN modülünden elde edilmiştir. Daha sonra ise CARRY4 makrosu kullanan modülden oldukça yakın bir süre elde edilmiştir. Bu iki bloğun diğerleri ile neredeyse yarı yarıya hızlı çalışmasının sebebi, bu blokta kullanılan toplama işlemi ve CARRY4 bloğunun toplama işlemine özel olarak optimize edilmiş olan belirli blokları kullanıyor olmasıdır. Özellikle PLUS_SIGN bloğu içerisinde yapılan tek satırda yazılan üç elemanın toplama işlemi sentezleyici tarafından carry-in içeren tek bir toplama modülüne çevrilmiş olup, böylece ciddi bir hızlanma elde edilmiştir. Ek olarak, bu bloklar çip üzerinde birbirine yakın lokasyonlarda bulunmakta, böylece iletişimi de ciddi anlamda hızlandırmaktadır. Diğer toplayıcı türlerinin, özellikle “with-select” statement kullanılan toplayıcının, kullandığı bloklarının çip içindeki yerleşimine bakıldığında ciddi anlamda optimizasyona açık olduğu kolayca görülebilmektedir. Bu bloklarda kullanılan alt blokların çip içerisinde daha iyi konumlandırılabileceği ve daha kısa mesafeler ile haberleştirilebileceği açıkça görülebilmektedir. İmplementasyon sonucu oluşan DATA_IN-CARRY_OUT veri yolu ve kullanılan SLICE’lar farklı devreler için aşağıda gösterilmiştir.