Elektronik Devreler Projeler Elektronik ve biraz daha fazlası İletişim - Araçlar - Dikkat - Topluluk
Elektronik / Mikrodenetleyici Projeleri/

Spartan3E FPGA Picoblaze Mikrodenetleyici Uygulaması

Sponsorlu Bağlantılar

Merhabalar, bu yazımda Xilinx firması tarafından tasarlanmış olan Picoblaze softcore mikrodenetleyicisinin FPGA içerisine gömülmesinden bahsedeceğim. Bu aralar bir süredir üniversitede aldığım FPGA dersi nedeniyle Xilinx FGPA çipleri ve VHDL dili ile uğraşma fırsatı buldum. Temel programlama bilgisi edindikten sonra ismini sürekli duymuş olduğum Xilinx’in softcore mikrodenetleyiclerini incelemeye başladım. Yaptığım araştırmalar ve uğraşmalar sonucunda Picoblaze denetleyicisini Basy2 Fpga kitim üzerinde koşturmayı başardım. Picoblaze kullanımı ile pek Türkçe anlatıma rastlamadığım için bu yazıyı yazmaya karar verdim. Bu yazı kapsamında Picoblaze denetleyicisini tanıtıp, denetleyicinin nasıl FPGA içerisine gömüleceğinden sırasıyla bahsetmeyi düşünüyorum.

Öncelikle Picoblaze’in kendisinden bahsedeyim. Picoblaze Xilinx firması tarafından tasarlanmış 8 bit softcore mikrodenetleyicisidir. Softcore olarak tasaranmıştır yani FPGA içerisine gömülüp koşturulabilir. Picoblaze’in genel özelliklerini aşağıda görebilirsiniz.

16 Byte genel amaçlı kaydediciler
1k x 18Bit Program Hafızası
Elde(Cary) ve sıfır(Zero) bildirim bayrakları bulunan byte girişli ALU
64 Byte dahili RAM
Harici çevre birimleri ile iletişim kurmak içim 256 giriş ve 256 çıkış kaydedicileri
31 Seviyeli stack(yığın)
2 clock çevrimde komut işleyebilme
200 MHz (100 MIPS) çalışma hızı (Virtex-II Pro FPGA üzerinde)
Hızlı kesme cevabı (5 saat çevrimi)
Xilinx Spartan 3E ailesi için optimize edilmiş düşük boyutlu mimari(yaklaşık 96 slice ve 0.5 Block RAM kullanımı)

Kullanılan FPGA ailesine göre biraz farklılık gösterse de temel özellikleri bu şekildedir. Örneğin daha üst seri FPGA ailelerinde program hafızası 4K’ya kadar çıkabilmektedir. FPGA ve mikrodenetleyiciler farklı mimariye sahip kontrolcülerdir. Haklı olarak aklınıza FPGA içine niye mikrodenetleyici gömüp kullanayım diye soru gelebilir. Bilindiği gibi FPGA’ler paralel işlem yeteneğine sahiptir yani bir çok işlemi aynı zamanda yapabilmektedir. Mikrodenetleyiciler ise ardışıl olarak işlemler yapabilmektedir. Bu mimari farklılıkları ise bazı işlemleri FPGA üzerinde bazı işlemleri de mikrodenetleyici üzerinde daha kolay yapmayı sağlar. Bu şekilde FPGA içerisine mikrodenetleyici çekirdekleri gömerek daha esnek tasarımı kolay sistemler tasarlayabiliriz. Picoblaze dışında Xilinx’in daha gelişmiş olan MicroBlaze, Altera’nın Nios II gibi softcore denetleyici çekirdeklerini, aynı zamanda piyasada popüler olan pic, 8051, arm v.s. denetleyici çekirdeklerini de FPGA içerisine gömüp koşturabiliriz. Bu yazıda temel olarak Picoblaze’in kullanıma değinip basit bir port okuyup yazma uygulaması yapacağız.

picoblaze-architec-kcpsm3-architecture-fpga

Picoblaze

Yukarıda resimde Picoblaze’in blok diygramını görebilirsiniz. Temel mikrodenetleyici yapılarına benzer bi yapıdadır. Resimde görüldüğü üzere diyagram üzerinde mikrodenetleyicilerde bulunan zamanlayıcı/sayıcı, Uasrt, SPI, I2C, I/0 portları gibi temel çevresel birimler bulunmamaktadır. Bunun yerine 256 adet giriş ve 256 adet çıkış portu bulunmaktadır. Yani ihtiyacınız olan çevresel birimi lojik olarak FPGA üzerinde tasarlayıp Picoblaze’in giriş/çıkış portlarına bağlayabilirsiniz. Bu sayede mikrodenetleyici çekirdeğini kendi ihtiyaçlarınız doğrultusunda şekillendirebilirsiniz. Kendi çevresel birimlerinizi tasarlamak başlangıç seviyesinde olanlar için zor bi işlemdir. Bunun yerine internette Picoblaze için tasarlanmış bir çok temel çevresel birimleri bulabilirsiniz. Basit birkaç atama işlemi ile bu çevre birimlerini Picoblaze ile haberleştirebilirsiniz. Biz bu temel uygulamamızda kitimiz üzerinde bulunan 8 adet lede bir çıkış portu 8 adet sürgülü anahtarla ise bir giriş portu atayıp temel giriş çıkış uygulaması yapacağız.

Picoblaze Kullanımı

Anlatılanları tam olarak anlayabilmek için temel FPGA bilgisine sahip olmak gerekmektedir. Xilinx ISE üzerinde proje oluşturma, dosya ekleme, simülasyon yapma, oluşturulan dosyaların FPGA üzerine gömülmesi gibi temel bilgilerini bilinmesi gereklidir. Picoblaze mikrodenetleyicisini kullanmak için ilk olarak Picoblaze sayfasından download butonuna tıklayarak Picoblaze dosyalarını içeren KCPSM3.zip dosyasını indirmeniz gerekmektedir. Dosyaları indirebilmek için üyelik gerekmektedir. Öncesinde Xilinx ISE programını indirmiş iseniz zaten üyesinizdir ama üye olmayanlar yada üyelik işlemleri ile uğraşmak istemeyenler yazının sonuna eklediğim bağlantıdan gerekli dosyalara ulaşabilirsiniz. Picoblaze kullanımı içn hem VHDL hemde Verilog dilini kullanabilmemiz mümkündür. Biz bu yazıda VHDL dilini kullanacağız. Anlatılan işlemler VHDL dili içindir.

kcpsm3-fpga-picoblaze-vhdl-xilinx-ise

Yukarıda resimde KPCSM.zip dosyasının içeriğini görebilirsiniz. Picoblaze kullanmamız için gerekli tüm doysaları burada bulabilirsiniz. Bu uygulamamızda Spartan3 ailesi FPGA kullanacağımız için ona uygun Picoblaze dosyalarını indirdim. Diğer FPGA ailelerinde ufak farklılıklar olabilir. Herhangi bi sorun olmaması için kullanacağınız FPGA ailesine göre derlenmiş dosyaları Xilinx’in sitesinden indirmeniz de yarar var. Bu dosyalar içinden bizim kullanacağımız Assembler klasörü ve VHDL klasöründeki kcpsm3.vhd dosyasıdır. Diğer dosyalarda çeşitli araçlar, örnek kodlar, verilog kodları v.s. açıklayıcı bilgileri bulabilirsiniz. Assembler dosyasında Picoblaze için yazacağımız asembly kodlarını derlemek için gerekli program, dosyalar ve örnek kodlar bulunur. İşlemleri sağlıklı bi şekilde yapabilmek için bu klasörü C dizinine kopyalamakta fayda var.

assembler-picoblaze-vhdl-xilinx-ise

Yukarıda şekilde Picoblaze assembler programının çalışması için gereken giriş dosyaları ve çıktı dosyaları görülmektedir. Picoblaze için yazdığımız asembly kodlarını herhangi bir metin editöründe yazıp .psm uzantılı kaydetmek yeterlidir. KCPSM3.exe dosyası dos ortamında çalışmaktadır. Bu yüzden derleme işlemi için komut satırını kullanmamız gerekmektedir. Ayrıca kcpsm3 programını çalıştırabilmek için 32bit mimariye sahip işletim sistemi gereklidir. Derleme yapabilmek için ROM_form.vhd, ROM_form.v, ROM_form.coe ve yazdığımız .psm uzantılı dosyanın KCPSM3.exe dosyası ile aynı klasörde olmalıdır. Yazdığımız kodları derlemek için komut satırını çalıştırmamız gereklidir. Bunun için başlat butonuna tıklayıp arama sekmesine cmd yazıp enter’a basmak yeterlidir. Örneğin oluşturduğumuz deneme.psm dosyasını derlemek için aşağıdaki komutları yazmak yeterlidir. deneme.psm dosyasını Assembler klasörüne atıp Assembler klasörünü de C: dizinine taşımayı unutmayın!


cd c:/Assmebler
kcpsm3 deneme.psm > error.txt

İlk komut satırında Assembler klasörümüzün içine giriyoruz. Sonrasında kaynak dosyamızı ve oluşturulacak hata dosyamızın ismini girerek programımızı çalıştırıyoruz. Yazığımız kodlarda hata yok ise hatasız bi şekilde derleme yapılır ve çıktı dosyaları oluşturulur. error.txt dosyasında ise derlemenin hatasız olarak yapıldığını belirtilir. Eğer yazmış olduğunuz kodlarda hata var ise komut satırında yazdığımı ‘> error.txt’ komutu sayesinde bu hatalar error.txt dosyası oluşturularak içine yazılır.

cd-cassmebler-kcpsm3-deneme-psm-error-txt-assembling

Yukarıda resimde derleme işlemi görülebilir. Komut satırına doğru komutlar yazıldığı takdirde kodlarımız doğru ise gerekli dosyalar üretilecektir. Derleme işleminde bir çok dosya üretilmektedir. Bunlar içinden bize gereken dosya program datalarının bulunduğu FPGA içerisine gömülecek olan deneme.vhd dosyasıdır. deneme.psm dosyasında yazdığımız kodlar doğrultusunda derlenmiştir. Aşağıda deneme.psm dosyamızın içeriğini görebilirsiniz.

deneme.psm


;Picoblaze Örnek test programı
 
			 CONSTANT inputs, 00	;Anahtarların bağlı olduğu giriş portu
			 CONSTANT outputs, 01	;Ledlerin bağlı olduğu çıkış portu
 
       loop:                        ;Döngü başlangıcı
			input s0, inputs		;Girişleri oku geçici değişkene aktar
			output s0,outputs		;geçici değişkendeki veriyi çıkışlara aktar
			jump loop				;İşlemi sürekli tekrarla

Yukarıda basit bi giriş okuma çıkışa yazma örneği yazdık. Picoblaze’in 256 giriş 256 çıkış portu olduğunda bahsetmiştim. Karışıklık olmaması için 0×00 nolu giriş portuna anahtarları 0×01 nolu çıkış portuna ise ledleri bağladım. Bu sayede programımız anahtarların durumuna göre ledleri yakıp söndürmektedir. Bilindiği gibi her mikrodenetleyicinin kendine özel asembly komutları bulunmaktadır. Aynı şekilde Picoblaze’inde kendine özel komut seti vardır. Bunları öğrenmek başlı başına bir ders konusu olduğu için bu yazımızda sadece basit bi giriş çıkış uygulaması yapılmıştır. Komutların açıklamalarına değinilmemiştir. Picoblaze denetleyicisi ile ilgili komutları ve daha detaylı bilgileri öğrenmek için yazının sonunda eklere dahil ettiğim Picoblaze kullanım kılavuzunu inceleyebilirsiniz. Bu şekilde kendi ihtiyacınıza göre daha kapsamlı programlar yazabilirsiniz. Programımızı derleyip deneme.vhd dosyasını elde ettikten sonra programımızı ve denetleyicimizi FPGA içerisine gömebiliriz.

picblaze_block-picoblazein-256-giris-256-cikis-portu

Yukarıda şekilde Picbolaze denetleyicimizin component bazında gösterimi görülmektedir. Picblaze temel olarak belli giriş çıkışları olan vhdl kodunda yazılmış dir dosyadır. Aynı şekilde bizim ürettiğimiz deneme.vhd dosyası da program komutlarını bulunduran vhdl dosyasıdır. Yapmamız gereken Xilinx ISE üzerinde yeni bir proje açıp bu .vhd dosyalarını biribirine elektriksel olarak bağlamak. Ayrıca örnek projemizde ledler ve girişleri için küçük bir adres çözümleme kodu yazmamız gerekmektedir. Bağlama işlemi temel olarak VHDL’de component tanımlama ve bağlantıları yapma işlemidir. VHDL’de component ekleme işlemine aşina olan ve temel VHDL bilgisi olanlar kolayca yaptığımız işlemi anlayabilir.

fpga-picoblaze-vhdl-xilinx-ise-proje

Ürettiğimiz program dosyasını ve Picoblaze denetleyicisini FPGA içerisinde gömmek için picoblaze_deneme.vhd gibi bir VHDL dosyası oluşturmak yeterlidir. Bu dosya içerisinde elimizde bulunan program dosyasını ve Picoblaze denetleyicisini bağlamamız ve girişler/çıkışlar için bikaç satır kod yazmamız gerekmektedir. Aşağıda picoblaze_deneme.vhd dosyamızın içeriğini görebilirsiniz.

picoblaze_deneme.vhd


----------------------------------------------------------------------------------
-- Engineer: Erhan YILMAZ
-- 
-- Create Date:    09/12/2012 
-- Design Name: 
-- Module Name:    picoblaze_deneme
-- Project Name:   picoblaze_deneme
-- Target Devices: xc3s100e-5cp132
-- Tool versions:  Xilinx ISE 13.3 (nt64)
-- Description: 
-- Revision: v1.0
-- Revision 0.01 - File Created
-- Additional Comments: This is a starting point design for using the picoblaze
-- soft core processor on the digilent basys2 Spartan3E starter kit.
-- Interfaces to the switches, buttons, and leds are provided as a 
-- quick start for any end application.
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
--FPGA çipinden dışarıya çıkarılan pinler
entity picoblaze_deneme is	
    Port ( clk : in  STD_LOGIC;		--Picoblaze clok girişi (Kit üzerinde 50 MHz osilatör)
           Ledler : out  STD_LOGIC_VECTOR (7 downto 0);	-- Kit üzerinde Çıkış Ledlerimiz
           girisler : in  STD_LOGIC_VECTOR (7 downto 0);-- Kit üzerinde giriş anahtarlarımız
			  reset_in : in std_logic);					-- Kit üzerinde Reset butonumuz
end picoblaze_deneme;
 
-- Ürettiğimiz program dosyasının giriş çıkışlarının component hali
architecture Behavioral of picoblaze_deneme is
component deneme is
    Port (      address : in std_logic_vector(9 downto 0);
            instruction : out std_logic_vector(17 downto 0);
                    clk : in std_logic);
    end component;
 
-- Picoblaze denetleyicimizin component hali
-- declaration of KCPSM3
  component kcpsm3 
    Port (      address : out std_logic_vector(9 downto 0);
            instruction : in std_logic_vector(17 downto 0);
                port_id : out std_logic_vector(7 downto 0);
           write_strobe : out std_logic;
               out_port : out std_logic_vector(7 downto 0);
            read_strobe : out std_logic;
                in_port : in std_logic_vector(7 downto 0);
              interrupt : in std_logic;
          interrupt_ack : out std_logic;
                  reset : in std_logic;
                    clk : in std_logic);
    end component;
 
-- Ara bağlantıları yapmak çeşitli sinyal tanımlamaları
signal out_port, port_id, in_port_reg : std_logic_vector(7 downto 0); --Çıkış portu, giriş portu ve port numarasını tutan sinyaller tanımlanır.
signal read_strobe, write_strobe, reset: std_logic; -- Okuma, Yazma ve Reset işaretleri için birer bitlik sinyaller tanımlanır.
signal address : std_logic_vector(9 downto 0);		-- Picoblaze adres hattı ile program dosyamızın adres hattını bağlamak için 10 bit adres sinyali tanımlanır.
signal instruction : std_logic_vector(17 downto 0); --Picoblaze komut hattı ile program dosyamızın data hattını bağlamak için 8 bit veri sinyali tanımlanır.
 
begin
 
--Program dosyamızın içinde bulunan program hafızası pinleri Picoblaze ve clock sinyaline bağlanır.
progrom : deneme port map (address => address, instruction => instruction,
						 clk=>clk);
 
-- Reset işaretimiz kit üzerindeki reset butonuna atanır.						 
reset <= reset_in; --unless you want to hook it to a button
 
-- Picoblaze denetleyicisinin tanımlanması ve pinlerini ataması yapılır.
-- Kesme kullanılmadığı için kesme girişi kullanılmadığı için lojik '0'a çekilmiştir.
pblaze : kcpsm3 port map
     (
	  address => address,
     instruction => instruction,
     port_id => port_id,
     write_strobe => write_strobe,
     out_port => out_port,
     read_strobe => read_strobe,
     in_port => in_port_reg,
     interrupt => '0',
     interrupt_ack => open,
     reset => reset,
     clk => clk
	  );
 
-- Tüm giriş ve çıkış atamaları clock işareti ile senkronize yapılır!	  
 
-- Bu process'te port id'sine göre kullanılan girişler Picoblaze denetleyicisinin giriş portuna yazılır.
-- Sadece 1 byte giriş (8 anahtar) kullandığımız için 0 numaralı giriş portu kullanılmıştır.
-- Picoblazein ürettiği port id numarası 0 olduğunda anahtarlar okunur. Diğer giriş birimlerinizi bağlayarak 
-- diğer id numaralarına atayabilirsiniz.
input_ports:process(clk)
	begin
		if rising_edge(clk) then
			case port_id is
				when x"00"  => in_port_reg <= girisler;
				--Örnek butonlar için giriş portu kullanımı
				--when x"01"  => in_port_reg <= Butonlar;
				when others => in_port_reg <= "XXXXXXXX";
			end case;
		end if;
	end process input_ports;	
 
-- Bu processte port id'sine göre kullanılan çıkışlar Picoblaze denetleyicisinin çıkış portuna yazılır.
-- Sadece 1 byte çıkış (8 LED) kullandığımız için 1 numaralı giriş portu kullanılmıştır.
-- Picoblazein ürettiği port id numarası 1 olduğunda Picoblaze'in çıkış portu LEDlere atanır. Diğer giriş birimlerinizi bağlayarak 
-- diğer id numaralarına atayabilirsiniz. Okuma process'inden farklı olarak yazma processinde write_strobe sinyalide kontrol edilir.
output_ports:process(clk)
	begin
		if rising_edge(clk) then
			if write_strobe='1' then
				if port_id=x"01" then
					Ledler <= out_port;
				end if;
			--Örnek LCD için çıkış port kullanımı
				--if port_id=x"02" then
					--LCD <= out_port;
				--end if;
			end if;
		end if;
	end process output_ports;
 
end Behavioral;

yukarıda picoblaze_deneme.vhd dosyamızı inceleyebilirsiniz. Kodların yanında gerekli açıklamalar yapılmıştır. Ayrıca vhdl dosyalarından hariç olarak picoblaze_deneme.ucf dosyası bulunmaktadır. Bu dosya ise yazdığımız programdaki giriş çıkışların FPGA pinlerine ataması ile ilgili bilgiler bulunmaktadır. Kullandığım kit basys2 kiti ve üzerinde xc3s100e-5cp132 FPGA çipi olduğu için tanımlamalar ona göre yapılmıştır. Aşağıda picoblaze_deneme.ucf dosyasının içeriğini görebilirsiniz. Ayrıca basys2 kiti ile ilgili detaylı bilgiye buradan ulaşabilirsiniz.

picoblaze_deneme.ucf


NET "clk" LOC = "B8" | IOSTANDARD = LVTTL;
NET "clk" PERIOD = 20.0ns HIGH 50%;
 
NET "reset_in" LOC = G12;
 
# PlanAhead Generated physical constraints 
 
NET "Ledler[0]" LOC = M5;
NET "Ledler[1]" LOC = M11;
NET "Ledler[2]" LOC = P7;
NET "Ledler[3]" LOC = P6;
NET "Ledler[4]" LOC = N5;
NET "Ledler[5]" LOC = N4;
NET "Ledler[6]" LOC = P4;
NET "Ledler[7]" LOC = G1;
NET "girisler[0]" LOC = P11;
NET "girisler[1]" LOC = L3;
NET "girisler[2]" LOC = K3;
NET "girisler[3]" LOC = B4;
NET "girisler[4]" LOC = G3;
NET "girisler[5]" LOC = F3;
NET "girisler[6]" LOC = E2;
NET "girisler[7]" LOC = N3;

Pin tanımlamalarını da yapıp projeyi sentezleyip yerleşimini yaptıktan sonra FPGA içerisine gömülecek olan .bit uzantılı dosyayı elde ediyoruz. Ürettiğimiz bu dosyanın basys2 kitine atılması için Digilent firmasının üretmiş olduğu Digilent Adept programını kullanacağız. Kullanımı çok basit olan programın arayüz görüntüsü aşağıdaki gibidir.

digilent-adept-programi

Adept programımızın görüntüsü yukarıdaki gibidir. Sentezleyicinin ürettiği .bit uzantılı dosya FPGA çipinin konfigürasyon verilerini içerir. Mikrodenetleyicilerdeki .hex .bin dosyaları gibidir. Xilinx ISE çeşitliği kitler için programlama desteği vermektedir. Fakat basys2 kiti için destek vermediği için Adept programı kullanılır. Üretilen bit dosyasını Adept programı ile FPGA içerisine attıktan sonra uygulamamız çalışmaya hazırdır. Aşağıda uygulamanın çalışma görüntüsünü görebilirsiniz.

picoblaze-basys2-digilent-beyond-theory