FPGA ile İşlemci Tasarımı / BT-I / #5 (ALU)

ALU yani aritmetik mantık ünitesi, matemetiksel işlemlerin yapıldığı modüldür. İşlemcinin çekirdeğini oluşturur. ALU nun yapabilecekleri ile bir işlemcinin gücü ölçülebilir. BT-I'in ALU'su oldukça basit bir yapıdadır. ALU sadece 16 bitlik toplama, çıkarma, and, or ve not işlemlerini yapabilmektedir. Tasarımı aşağıdaki gibidir:

Arithmetic Unit: Toplama ve çıkarma işlemlerinin yapıldığı ünite. VHDL kodu:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity Add_Sub is
    port(A, B : in std_logic_vector(15 downto 0);   --Girişler
        Operation : in std_logic_vector(1 downto 0); --ADD, ADC, SUB işlemlerinin seçimi
        Carry_Update : in std_logic;                 --Bayrağı günceller
        Carry_In : in std_logic;                     --Carry bayrak girişi
        Carr_Out : out std_logic;                    --Carry bayrak çıkışı
        O : out std_logic_vector(15 downto 0));      --Çıkış
end Add_Sub;

--Operation = "00" -> ADD
--Operation = "01" -> ADC
--Operation = "10" -> SUB
--Operation = "11" -> SUB

architecture Behavioral of Add_Sub is

--Komponent tanımlaması
component FA
    port(A, B, Cin : in std_logic;
        O, Cout : out std_logic);
end component;

    signal Carry : std_logic_vector(16 downto 0) := (others >; '0');
    signal FA_B : std_logic_vector(15 downto 0);
    
begin

    --Çıkarma işlemi yapılcaksa B sinyalini tersle
    U1 : for i in 0 to 15 generate
        FA_B(i) <= Operation(1) xor B(i);
    end generate;
    
    --Full-Adder ların bağlanması
    U2 : for i in 0 to 15 generate
        U2 : FA
            port map(A(i), FA_B(i), Carry(i), O(i), Carry(i + 1));
    end generate;
    
    --SUB yada ADC komutları için elde girişini ayarla
    Carry(0) <= Operation(1) or (Carry_In and (Operation(0) and (not Operation(1))));
    
    --Carry_Update '1' ise bayrağı güncelle
    Carr_Out <= (Carry_In and (not Carry_Update)) or (Carry(16) and Carry_Update);
    
end Behavioral;

Logic Unit: And, or ve not işlemlerinin yapıldığı ünite. VHDL kodu:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity Logic_Unit is
    port(A, B : in std_logic_vector(15 downto 0);  --Girişiler
        Sel : in std_logic_vector(1 downto 0);      --İşlem seçme ucu
        O : out std_logic_vector(15 downto 0));     --Çıkış
end Logic_Unit;

--Sel = "00" -> AND
--Sel = "01" -> OR
--Sel = "10" -> NOT
--Sel = "11" -> NOT

architecture Behavioral of Logic_Unit is
    
    signal AndOut : std_logic_vector(15 downto 0);
    signal OrOut : std_logic_vector(15 downto 0);
    signal NotOut : std_logic_vector(15 downto 0);
    
begin
    
    AndOut <= A and B;
    OrOut <= A or B;
    NotOut <= not A;
    
    with Sel select
        O <= AndOut when "00",
              OrOut when "01",
              NotOut when others;
    
end Behavioral;

Modüllerin birleştirilmesi:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity ALU is
    port(A, B: in std_logic_vector(15 downto 0);                  --Girişiler
        Arithmetical_Operations : in std_logic_vector(1 downto 0); --Aritmetik işlemler seçim ucu
        Logic_Operations : in std_logic_vector(1 downto 0);        --Mantık işlemleri seçim ucu
        ALU_Operations : in std_logic;                             --Aritmetik-Mantık seçim ucu
        Flags_Update : in std_logic;                               --Bayrakları güncelle
        Flags_In : in std_logic_vector(1 downto 0);                --Bayrak girişi
        Flags_Out : out std_logic_vector(1 downto 0);              --Bayrak çıkışı
        O : out std_logic_vector(15 downto 0));                    --İşlem sonucu
end ALU;

architecture Behavioral of ALU is

--Komponent tanımlamaları
component Add_Sub
    port(A, B : in std_logic_vector(15 downto 0);
        Operation : in std_logic_vector(1 downto 0);
        Carry_Update : in std_logic;
        Carry_In : in std_logic;
        Carr_Out : out std_logic;
        O : out std_logic_vector(15 downto 0));
end component;

component Logic_Unit
    port(A, B : in std_logic_vector(15 downto 0);
        Sel : in std_logic_vector(1 downto 0);
        O : out std_logic_vector(15 downto 0));
end component;

    signal Add_Sub_Out : std_logic_vector(15 downto 0);
    signal Logic_Out : std_logic_vector(15 downto 0);
    signal ALU_Out : std_logic_vector(15 downto 0);
    signal Zero : std_logic;
begin

--Komponentlerin birleştirilmesi
    U1 : Add_Sub
        port map(A, B, Arithmetical_Operations, Flags_Update, Flags_In(0), Flags_Out(0), Add_Sub_Out);
        
    U2 : Logic_Unit
        port map(A, B, Logic_Operations, Logic_Out);
    
    with ALU_Operations select
        ALU_Out <= Add_Sub_Out when '0',
                      Logic_Out when others;
        
    with ALU_Out select
        Zero <= '1' when X"0000",
                  '0' when others;
                  
    Flags_Out(1) <= (Zero and Flags_Update) or ((not Flags_Update) and Flags_In(1));
    
    O <= ALU_Out;
    
end Behavioral;

Aşağıda Quartus II programının oluşturduğu RTL modelleri görülmektedir:

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir