Arkadaşlar her zaman konuştuğumuz ‘bilgisayarın işlemcisi intel ya da amd 2.4Ghz’ gibi terimleri duyagelmişizdir. Ve yine intel ve amd’nin bu işten çok para kazandığını az ya da çok bilmekteyiz. Peki nedir bu işlemci, yapısı, çalışma mantığı nasıldır, ne olur da işlemci verdiğimiz görevleri eksiksiz yerine getirebilir, neden bazı işlemcilerde az kodla çok iş yaparken bazılarında daha çok kod yazmak zorundayız, veri yolu, işlem kapasiteleri de ne demek ve bunun gibi bir çok soruya cevap vermesini dilediğim bir tasarım başlığı açmak istedim
Kısaca yapacağımız işleme ve uygulama adımlarına değinecek olursak:
- 1) CPU Nedir?
- 2) Single Cycle Computer Çalışma Mantığı
- 3) Veri Yolu ve Kontrol Ünitesi
- 4) VHDL ile Tasarımın Gerçekleştirilmesi
- 5) Tasarımın Oluşturulması ve Denenmesi
Bölüm 1 – CPU Nedir?
Bir bilgisayarın en önemli parçalarından biri işlemcidir. Kısaca CPU (Central Processing Unit) ya da MİB (Merkezi İşlem Birimi) olarak anılan ve adından da anlaşılacağı üzere bilgisayardaki işlemleri sayısal
olarak yürüten ve sonuçları gerekli yerlere gönderen elemanlardır. İşlemciler aritmetik ve mantıksal işlem yapabilme yeteneğine sahiptirler. Bu işlevlerini kullanabilmek için işlemci içerisine tanımlanmış, komut listelerinden ibaret bir takım programlar mevcuttur.
Bu komutlar işlemciye iki sayının toplamı, çıkarılması yönünde emirler verebildiği gibi dış çevreden (örneğin klavyeden, yazıcıdan, fareden) alacağı emirlere göre bir takım komutları atlayıp başka komut
satırlarını işlemeye devam edebilir. Temel olarak işlemcinin yaptığı iş, bitler üzerinde işlem yapmak üzere belirlediğimiz komutları çalıştırmaktır. CPU veya çeşitli donanım aygıtlarını kontrol edebilecek öte yandan kullanıcının rahatça vereceği komutları gerekli yerlere ulaştıracak bir sisteme ihtiyaç vardır.
Temelde bu sistemler bilgisayarlarda yazılım tabanlıdır ve görevi diğer yazılımların belleğe, girdi/çıktı aygıtlarına ve kütük sistemine erişimini sağlar. Birden çok program aynı anda çalışıyorsa, işletim sistemi her programa yeterli sistem kaynağını ayırmaktan ve birbirleri ile çakışmamalarını sağlamaktan da sorumludur. Yapacağımız işlemci 8 bitlik veriyoluna sahip, yaklaşık 30 komutu rahatlıkla işleyebilen, harvard mimarisine sahip single cycle computer olacaktır.
Resim 1 – Single Cycle Computer
Bölüm 2 – Single Cycle Computer
2.1) İşlemci Mimarileri
2.1.1) Von Neumann Mimarisi: John Von Neumann’ın 1945′teki makalesinde adı geçen ve bilgisayar tarihinde ilk kez ortaya atılan mimaridir. Basit bir temel üzerine kurulu olan yapıda kısaca komut hafızası ve veri hafızanın birlikte bulunduğu tek bir bellek elemanı, komutları işlem sırasına sokan denetim birimi ve istediğimiz işlemi yapmak için ise gelişmiş bir ALU’ya (CPU) sahiptir.
Von Neumann mimarisinin en büyük eksikliği kaydedicilerin ve hafızanın aynı bellekte elemanı üzerinde bulunmasıdır. Bu ona hız konusunda büyük eksiklikler getirir. Genelde CISC işlemciler bu mimariyi baz alır ve oldukça fazla komuta sahiptirler. Buna örnek olarak Intelin 8051 mikrodenetleyicisi (255 komut içerir) gösterilebilir.
Şekil 2 – Von Neumann Mimarisi
2.1.2) Harvard Mimarisi: Von Neumann’ın eksikliklerini gören IBM ve Intel mühendislerinin bir araya gelerek oluşturdukları mimaridir. Mühendislerin yaptığı ise komut hafızası ile veri hafızasını birbirinden ayırmaktır. Böylece bir komut işlenirken belleğe yazma işlemi beklenmemekte ve dolayısıyla hız artmaktadır. Genelde RISC işlemciler bu mimariye dayanmaktadır ve oldukça az komuta sahiptirler. Dolayısı ile işi işlemciyi programlayacak kişiye bırakır. Örnek olarak Microchip firmasının Picleri (16f serisi 35 komut içerir) ve daha birçok mikrodenetleyicisi ve günümüz işlemcileri (pentium vb.) gösterilebilir.
Şekil 3 – Harvard Mimarisi
2.2) Single Cycle Computer: Adının da belirttiği gibi bir komutu tek bir adımda işleyen en basit CPU yapısıdır. Harvard mimarisine sahip CPU, kısaca veri yolu ve kontrol ünitesinden oluşur (3. bölümde anlatılacak). İşlemcimiz dışarıdan sağlayacağımız saatin frekansına göre çalışır ve o frekansla hızı anılır fakat tasarımda kullanılan malzemelerin hız değerleri, örneğin memory’e yazma hızı gibi etkenler CPU’nun çalışma hızını etkiler. Yapıda en yavaş çalışan bölüm, hız belirleme açısından en önemli bölüm olmaktadır.
2.3) Çalışma Mantığı:
-Programcı öncelikle yapmak istediği işlemleri komut hafızasına (Instruction Memory) yükler,
-Daha sonra CPU çalıştırılmaya başlanır,
-Program Counterher bir saat darbesinde birer artar (bu değiştirilebilir),
-Her bir PC değerine göre gerekli kod işletilir,
-İstenilen değerler Registerlere yüklenir,
-Bu değerler ile gerekli işlemler yapılır,
-Gerekirse işlem sonuçları hafızaya alınır,
-Komutlar bittiğinde program sonlanır.
Örnek bir işlem yaptırmak istersek; *8 register tanımladığımızı R1=4, R4=5 olduğunu gerisinin ise ‘0′ olduğunu kabul edelim
*Komut belleğine ise
0) R3=R1+R4
1) R2=R3*R1
2) R5=R2/R4 olarak tanımlansın.
*PC değerimiz sırasıyla 0,1,2,3.. şeklinde gidecek ve komutlar sırasıyla işletilecektir.
*Sırayla işlemler yapıldığında son değerlerimiz;
R3=9
R2=36
R5=7,2 olacaktır.
*Tüm bu işlemler toplamda 3 clock cycle süre alacaktır.
Şekil 4 – Veri Yolu Yapısı
Bölüm 3 – Veri Yolu ve Kontrol Ünitesi
3.1) Veri Yolu: Veri yolu, işlemcinin yükünü çeken kısmıdır. Verilen komutlara göre sırasıyla çıkarma, toplama, çarpma gibi tüm işlemler bu kısımda yapılır. Çıkan sonuçlara göre bizlere kontrol etme olanağı da sağlayan bölümlere sahiptir. Kabaca veri yolu yukarıda görüldüğü gibi şu parçalardan oluşur;
– Register Birimi
– Fonksiyon Ünitesi
– Hafıza Elemanı
Şekil 1 – Veri Yolu
3.1.1. Register Birimi: İşlemlerde geçici hafıza olarak kullanılan bölümdür. Projemizde toplam 8 adet, 8 bitlik register kullanılacaktır. Register içerikleri istenildiği zaman dışarıdan kontrolle sıfır yapılabilmekte ve yine istediğimiz komuta göre istenilen registere, istenilen değer atanabilmektedir.
3.1.2. Fonksiyon Ünitesi: Veri yolunun en önemli yapısıdır. Toplama, çıkarma, çarpma, ‘and’ ve ‘or’ gibi aritmetik ve mantıksal işlemleri yerine getirebilmek için tasarlanmış bölüm burasıdır. Tasarımımızda 8 bitlik, 15 işlemi gerçekleştirebilen ALU tasarlanacaktır. İşlem sonuçlarına göre taşma (V), toplam sonuçlarında elde (C), negatiflik (N) ve sonucun sıfır (Z) olup olmadığını kontrol edebileceğimiz bit çıkışları da yine aynı yapı
içerisine gömülmüş olup ayrıca bu bayrakları da yine bu yapıdan kontrol edilebilir.
3.1.3. Hafıza Elemanı: İşlemcide istediğimiz bilgiyi saklamak için kullanabileceğimiz, gerektiği zaman tekrar sakladığımız bilgiyi kullanabileceğimiz bölümdür. Tasarımızda 8×8 bitlik memory kullanacak olup şekilde görülen address out ve data out
kısımları ile bu elemanın kontrolünü sağılanacaktır.
Şekil 2 – Kontrol Ünitesi
3.2) Kontrol Ünitesi: Veri yolu tasarlandıktan sonra verilen komutları sıralayan, kontrol eden ve düzenleyen kısım burasıır. Bu bölüm daha önceki bahsettiğimiz Harvard mimarisinin bire bir yansımasıdır. Yukarıdaki resimde görülen kontrol ünitesi aşağıdaki birimlerden oluşur:
– Program Counter Birimi
– Komut Hafızası
– Komut Çözücü
3.2.1. Program Counter Birimi: Seri işlemcilerin en büyük özelliklerinden biri olan, sırayla işlem yapma özelliğini kazandıran bölümdür. Görevi her saat darbesinde bir artmak ya da atlama komutu verildiğinde istenilen program koduna ulaşmayı sağlamaktır. Bu tasarımda kullanıcının da kontrol edebileceği, 8 bitlik sayıcı tasarlanacaktır.
3.2.2. Komut Hafızası: İşlemcinin hangi sırayla, hangi işlemleri yapacağı bilgisini saklandığı bölümdür. Şekil-2’de görülebilecek (Instruction Memory) bu kısım, özellikle işlemciyi programlayacak kişi tarafından algoritmalar geliştirilip, bu bölüme yükleme yapılmasıyla anlam kazanmaktadır. Bölüm kısaca aldığı program counter değeri ne ise, o kısmı işletme emri vermekle yükümlüdür.
Yapılan tasarımda işlemciye 28 işlemi art ardına yapabilme özelliği kazandırılmıştır. Bu da basit bir algoritma yazacak programcı için oldukça yeterli bir hafızadır.
3.2.3 Komut Çözücü: Kontrol ünitesinin en önemli kısmıdır. Kullanıcı tarafından makine dilinde yazılan kodun çözüldüğü, veri yoluna hangi görevlerin yaptırılacağı, hafızaya değer alımları, atlama emirleri ve bunun gibi birçok komutun süzüldüğü yer burasıdır. Yapılan tasarımda 16’ya 17’lik kod çözücü tasarlanacaktır.
3.3) Hızı Etkileyen Unsurlar: Hızı etkileyen en büyük unsur veri yolundaki yavaşlıktan kaynaklanır. Genel anlamda ne kadar hızlı bir veri yolu tasarlanırsa o denli hızlı işlemci elde etmek mümkündür. Gelişen teknoloji ve kullanılan değişik mimari metotları ile (mesela pipeline) bu bölümü hızlandırmak mümkündür. Günümüz işlemcilerinde birden fazla veri yolu bulunmakta ve dahası bunlar paralel çalışarak işlemciye hız konusunda büyük özellikler kazandırmaktadır.
3.4) İşlemcimizin İşletebileceği Kodlar: İşlemcimiz şekil-3’teki kodları rahatlıkla işletebilecek bir yapıya kavuşacaktır. Bu kodlar basit işlemler için oldukça yeterlidir. Tablonun en başında işlemlerin adı daha sonra sırayla işlem kodu, kısaltması, etkilenecek registerler, registerlerin nasıl işleme tabi tutulacağı ve hangi bayrakların bundan etkilenebileceği gösterilmiştir.
Şekil 3 – Tanımlı İşlemler
Şekil-3’teki kodlar yapılacak işleme göre seçilip komut hafızasına yani instruction memorye şekil-4’teki sırayla yerleştirilmelidir.
Şekil 4 – Adresleme Modları
3.5) Örnek Bir İşlem: Şekil-5’teki işlemlerimi seçtiğimizi düşünelim. Sırasıyla yapılacak işlemleri tanımlayacak olursak:
- 0) R2’den R3 çıkartılıp R1’e atanacak
- 1) R6 bir sola kaydırılıp R4’e aktarılacak
- 2) R7’nin içeriği bir artırılacak
- 3) R0, 2 sayısı ile toplanıp R1’e atanacak
- 4) R3’ün değeri kaydedilecek
- 5) O anki data R4’e yazılacak
- 6) Son olarak R5’e reset atılacak.
Şekil 5 – Yapılacak İşlemler ve Etkilenen Veri Yolu Öğeleri
Şekil-5’teki işlemler yapılırken kontrol ünitesinin, veri yolunda hangi seçimleri yaptığı açıkça gözükmektedir.
Şekil 6 – Değişen Veri Yolu Değerlerinin Sayısal Değerleri
Daha anlaşılır olması için şekil-6’da hangi yapının hangi giriş ya da çıkış değerine göre kontrol edildiği işlemine göre gözükmektedir. İşlemin oluşması ise şöyle gerçekleşir: 1) Tüm bu işlemler komut hafızasına sırayla şekil-4’teki adresleme modlarından uygun olanı seçilerek yüklenir. 2) İşlemci çalıştırılır. 3) Program counter saymaya başlar ve komut hafızasının ilk adresinden itibaren kodları okutmaya başlar.
4) Şekil-4 teki adresleme moduyla kodlanmış komutlar komut çözücüye gelir ve veri yolunun anlayabileceği şekil-6’da gözüken şekilde dağıtılır.
5) Kullanılacak registerler, fonksiyonlar seçilir ve işlem bir saat darbesi içerisinde biter. 6) Daha sonra durum bir kez daha 3. maddeye döner ve bu sefer yeni bir komut alınarak işlemler devam eder. İşlemler devam ederken oluşan zaman diyagramı ise şekil-7’de gözükmektedir.
Şekil 7 – Zaman Çizelgesi
Bölüm 4 – VHDL ile Tasarımın Gerçekleştirilmesi
Tasarımın bu aşamasında VHDL diline az çok hakim olmak gerekiyor. Bu konuda sizlere MIT’nin Circuit Design with VHDL’ kitabını baştan sona örnekleriyle birlikte iyice irdelemenizi tavsiye ederim.
Şekil 1 – Single Cycle Computer
Burada single cycle’ın mimari yapısı görülmektedir. Her yapının kendine has özellikleri bulunmak ile birlikte VHDL ile tasarımda bir kaç kod yazılarak elde edilebilmektedir. Biz burada CPU’nun en önemli parçalarından biri olan Function Unit yani hepimizin bildiği tabirle gelişmiş bir ALU’yu VHDL ile tasarlayalım.
--www.FxDev.org library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity ALU is Port ( A,B : in STD_LOGIC_VECTOR (7 downto 0); F_SEL : in STD_LOGIC_VECTOR (3 downto 0); V,C,N,Z : out STD_LOGIC; F : out STD_LOGIC_VECTOR (7 downto 0)); end ALU; architecture Behavioral of ALU is signal temp_a,temp_b: std_logic_vector(8 downto 0); signal sonuc : std_logic_vector(8 downto 0); signal topla : std_logic_vector(7 downto 0); begin temp_a <= '0' & A; temp_b <= '0' & B; with F_SEL select --Aritmetik Kısım-- sonuc<= temp_a when "0000", temp_a + 1 when "0001", temp_a + temp_b when "0010", temp_a + temp_b +1 when "0011", temp_a + (not temp_b) when "0100", temp_a + (not temp_b) + 1 when "0101", temp_a - 1 when "0110", --Logic Kısım temp_a when "0111", temp_a and temp_b when "1000", temp_a or temp_b when "1001", temp_a xor temp_b when "1010", not temp_a when "1011", temp_b when "1100", --Kaydırmalar-- '0' & temp_b(8 downto 1) when "1101", --B'yi bir sağa kaydır... temp_b(7 downto 0) & '0' when "1110", --B'yi bir sola kaydır... (others => 'Z') when others; topla <= ('0' & A(6 downto 0))+ ('0' & B(6 downto 0)); F <= sonuc(7 downto 0); --Sonuç V <= sonuc(8) xor topla(7); --Taşma Var C <= sonuc(8); --Toplamın Eldesi N <= '1' when sonuc(7)='1' else '0'; --Sonuç Negatif Z <= '1' when sonuc(7 downto 0)="0000000000000000" else '0'; --Sonuç Sıfır end Behavioral;
Kodlara bakıldığında aslında işin o kadar da zor olmadığı gözükür. Aslında yukarıdaki tüm işlemler biz seçmesek dahi yapılır, bizim istediğimiz ise o yapılan işlemlerden bize özel olanı seçmektir. Buradaki V bayrağı taşmayı, N bağrağı negatifliği, Z sıfır olmayı ve C ise toplam sonucunda elde olup olmadığının bilgilerini bizlere vermektedir. Girdiler A ve B kanallarından 8bit şeklinde alınıp sonuç yine F kanalından 8bit büyüklüğünde çıkmaktadır. Fonksiyon ünitesi işlemci saatinden bağımsız olup, kombinasyonel bir devredir.
Kodları hangi sırayla nasıl yürüteceğimiz ise Instruction Memory’e yükleyeceğimiz değerlerle alakalıdır. Komut hafızamızın kodları aşağıda görüldüğü üzere gayet sadedir.
--www.FxDev.org-- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity Inst_Memory is Port ( Adress : in STD_LOGIC_VECTOR (7 downto 0); Inst : out STD_LOGIC_VECTOR (15 downto 0)); end Inst_Memory; architecture Behavioral of Inst_Memory is begin with Adress select ---|Opcod||D||A||B|--- Inst <= "0000010011011111" when "00000000", "0000001001001000" when "00000001",
Komutlar yukarıda belirtildiği sırada yerleştirilmeli, yani önce opcode, sonra D adresi, sonra A ve B. Opcode yapacağımız işlemin özel kodududur ve 3. bölümde açıklamalı bir şekilde bunların neler olduğu açıklanmıştır.
Bölüm 5 – Tasarımın Oluşturulması ve Denenmesi
Bu bölümde;
-Tasarımın Oluşturulması ve Denenmesi
-Simülasyon Çıktılarına bakıp CPU tasarımımızı sonlandıracağız…
4. bölüm’de verdiğim kodları Xilinx Ise programıyla açıyoruz. Oradan Inst. Memory’ye gidip aşağıdaki şekilde kodları girebiliriz, ben örnek olarak aşağıdaki resimdeki işlemleri yapmayı uygun gördüm. Siz de bölüm 3′te verilen kodlarla istediğiniz şekilde program kodlarınızı yazıp koşturtabilirsiniz.
Şekil 1 – Örnek Kodlar
Şekilde görülen işlemleri Xilinx simülasyon programıyla test ettiğimizde aldığımız görüntü aşağıdaki gibi olmakta ve bu da işlemcimizin doğru çalıştığını bize göstermektedir.
Şekil 2 – Simülasyon Sonuçları
Diğer VHDL Kodları:
Şifre-Pass: 320volt.com
PicProje E-Dergi 2 | Yazar: FxDev
Yayım tarihi: 2018/07/05 Etiketler: cpu tasarımı, kılavuz ders, VHDL