Bu yazımızda kayan noktalı sayılarda çarpma işlemini pipeline mimaride fonksiyonlar ile gerçekleştirilmesini anlatacağız.
Kayan noktalı sayılarda dört işlemle ilgili detaylı yazımıza buradan ulaşabilirsiniz.
Yazıda çarpma işlemlerine ait gösterilen tüm adımlar birer fonksiyon olarak tanımlanmıştır.
Aşağıda VHDL dili kullanılarak kayan noktalı sayılarda çarpma işlemini gerçekleştiren fonksiyon kodları verilmiştir. Koddan da görüleceği üzere ilk olarak işaret biti tanımlama işlemleri gerçekleştirilmektedir. Burada saklayıcı amacı ile değerin saklnamasının nedeni pipeline mimarini işletilebilmesidir. İkinci kısımda ise çarpan değerinin hesaplandığı fonksiyonlar ve üçüncü kısımda bu mantis değerinin hesaplandığı fonksiyonlar gösterilmiştir.
Sabit atamalarında kullanılan g_e üst değerinin saklanacağı bit sayısını, g_f ise mantis değerinin saklanacağı bit sayısını göstermektedir.
Bu fonksiyonlarda sıfırla çarpma, sonsuzla çarpma gibi bazı kontroller eksik bırakılmıştır.
..... constant g_e : natural := 8; constant g_f : natural := 23; ..... ..... out_rslt <= r_s_rslt & r_e_rslt & r_f_rslt; -- işaret bitini belirle r_s_rslt <= r_s_rslt_reg ; r_s_rslt_reg <= sign_bit_calc_m_d(in_a_nmb(in_a_nmb'high), in_b_nmb(in_b_nmb'high)); -- üst kısımların hesaplanma işlemleri r_exp_add_rslt <= exp_calc_m(in_a_nmb(g_e + g_f - 1 downto g_f), in_b_nmb(g_e + g_f - 1 downto g_f)); -- r_e_rslt <= exp_update_m(r_exp_add_rslt, r_mant_mul_rslt(r_mant_mul_rslt'high)); --çarpan kısmının hesaplanması r_mant_mul_rslt <= mantissa_calc_m(in_a_nmb(g_f - 1 downto 0), in_b_nmb(g_f - 1 downto 0)); -- r_f_rslt <= mant_update_m(r_mant_mul_rslt, r_mant_mul_rslt(r_mant_mul_rslt'high));
sign_bit_calc_m_d fonksiyonu ile iki sayının çarpımı sonucunda elde edilecek sayının işaret biti değerini döndürmektedir.
function sign_bit_calc_m_d( a_sign, b_sign : std_logic) return std_logic is begin return a_sign xor b_sign; end sign_bit_calc_m_d;
exp_calc_m fonksiyonu ile iki sayının çarpımı sonucunda üst kısmını hesaplama sonucunu döndürmektedir.
function exp_calc_m(a_exp, b_exp : std_logic_vector(g_e - 1 downto 0)) return std_logic_vector is begin return (a_exp + b_exp - conv_std_logic_vector(2**(g_e - 1) - 1, g_e)); end exp_calc_m;
exp_update_m fonksiyonu ile çarpanlarn çarpımı sonucuna göre nihai üst değerini döndürmektedir.
function exp_update_m(exp_add : std_logic_vector(g_e - 1 downto 0); mant_bit : std_logic) return std_logic_vector is begin if mant_bit = '0' then return exp_add; else return exp_add + 1; end if; end exp_update_m;
mantissa_calc_m fonksiyonu çarpanlarn çarpımı sonucuna döndürmektedir.
function mantissa_calc_m(a_mant, b_mant : std_logic_vector(g_f - 1 downto 0)) return std_logic_vector is variable mant_mul_rslt : std_logic_vector(2 * g_f + 1 downto 0) := (others => '0'); begin mant_mul_rslt := ('1' & a_mant) * ('1' & b_mant); return mant_mul_rslt(mant_mul_rslt'high downto mant_mul_rslt'high - g_f - 1); end mantissa_calc_m;
mant_update_m fonksiyonu çarpanlarn çarpımı sonucunun nihai değerini döndürmektedir.
function mant_update_m(mant_mul : std_logic_vector(g_f + 1 downto 0); mant_bit : std_logic) return std_logic_vector is begin if mant_bit = '0' then return mant_mul(mant_mul'high - 2 downto mant_mul'high - g_f - 1 ); else return mant_mul(mant_mul'high - 1 downto mant_mul'high - g_f); end if; end mant_update_m;