FPGA ile Sonlu Durum Makinesi Uygulaması


JpegFPGA ile (Sahada Programlanabilir Mantık Dizeleri) gerçekleştirilen bu örnek uygulamamızda geliştirme kartımız üzerinde bulunan 8 adet (4×2 display bloğu) 7 segment display ile 2 adet Sonlu Durum Makinesi(SDM) örneği uygulaması yapacağız. Bu uygulamalar sırası ile;

  1. Geliştirme kartı üzerindeki butona basıldığında bunu “lojik 1” değeri olarak algılayıp, bir sonraki duruma geçen, 8 adet (4×2 display bloğu) 7 segment display üzerinde 0’dan 7’ye kadar sayan sonlu durum makinesi örnek uygulaması
  2. Geliştirme kartındaki 8 adet (4×2 display bloğu) 7 segment display üzerinde 0’dan F’ye kadar zamana bağlı olarak bir sonraki duruma geçen, sonlu durum makinesi örnek uygulaması

Sonlu Durum Makinesi(Finite State Machine) nedir?

Sonlu Durum Makinası (veya durum makinası), sınırlı sayıda durumdan, durumlar arası geçişlerden ve eylemlerin birleşmesiyle oluşan davranışların bir modelidir.

sdm

Yukarıdaki görselde basit bir durum makinesinin mantıksal çalışması gösterilmiştir. A,B,C olarak 3 adet durum tanımlaması yapılmıştır. Girişten “lojik 1” değeri geldikçe durum, bir sonraki duruma doğru ilerleyecektir. Son durum olan C durumunda da gene “lojik 1” değeri geldiğinde işlem tamamlanmış olacaktır. Herhangi bir durumda lojik 0 değeri geldiğinde ise makine A durumuna geri dönecektir.

Örneğin bir yazı editörü içinde bir metinde “FPGA” kelimesini aradığımızı varsayalım. Kelime 4 harfli olduğu için, dört durum oluşacaktır, bunlara; DurumA, DurumB, DurumC ve DurumD diyelim.

DurumA; FPGA kelimesinin ilk harfi olan “F” harfini arayacak, bulursa DurumB aşamasına geçecek, bulamazsa ise DurumA, durumunda kalacak ve çıkış ise “0” değerinde olmayı sürürecek. DurumB’de makine “P” harfini bulduğunda DurumC’ye geçecek. DurumC‘de “G” harfi bulunduğunda DurumD’ye geçilecek bulunamaz ise DurumA durumuna geri dönecek ver herşey yeniden başlayacak. DurumD’de ise “A” harfi bulunduğunda “FPGA” kelimesi tamamlanmış olacak ve kelimenin bulunduğunu belirten çıkış durumu ise “1” değerinde olacak.

Sonlu Durum Makineleri(SDM) Moore ve Mealy Makinesi olarak temelde iki tipe ayrılmaktadırlar.

Moore Makinesi, sadece giriş eylemlerini kullanır, çıkış duruma bağlıdır. Moore Makine modelinin avantajı, davranışın basitleşmesidir.

Mealy Makinesi, sadece girdi eylemlerini kullanır, çıktı girdi ve duruma bağlıdır. Mealy SDM’lerinin kullanımı durum sayısının azalmasını sağlamaktadır.

Biz örneklerimizde, Moore Makinesi yapısındaki Verilog HDL tasarımını kullanacağız.

Örnek kodlarının içerisinde, aşağıdaki tabloda gösterildiği gibi önce, durumlar tanımlanır;

 //-------------Parametre Tanımlamaları--------------------
parameter
durum0=3'b000,    //0. durum
durum1=3'b001,    //1. durum
durum2=3'b010,    //2. durum
durum3=3'b011,    //3. durum
durum4=3'b100,    //4. durum
durum5=3'b101,    //5. durum
durum6=3'b110,    //6. durum
durum7=3'b111;    //7. durum

Burada 0’dan 7’ye kadar olan, 8 durum 3 bit olarak tanımlanmıştır.

Sondasında durum(case) ifadesi yapısında tüm durumlar bir sonraki durumu ifade edecek şekilde düzenlenmiştir. Burada dikkat edilmesi gereken nokta, durum7 durumunun bir sonraki durumuna, durum0 yüklemesi yapılarak döngü sürekli hale getirilmiştir. Eğer döngünün durum7 durumundan sonra sona ermesini istiyorsanız, ikinci örnekte de olduğu gibi son durumu yoruma çekebilirsiniz. Bu durumda duran döngüyü sıfırlama butonuna basarak bir sonraki sefer için başlatabilirsiniz.

case(durum) //koşula göre durum seçimi
durum0:                      //durum0
durum<=durum1;    //sonraki durumun yüklenmesi durum1
durum1:                      //durum1
durum<=durum2;    //sonraki durumun yüklenmesi durum2
durum2:                      //durum2
durum<=durum3;    //sonraki durumun yüklenmesi durum3
durum3:                      //durum3
durum<=durum4;    //sonraki durumun yüklenmesi durum4
durum4:                      //durum4
durum<=durum5;    //sonraki durumun yüklenmesi durum5
durum5:                      //durum5
durum<=durum6;    //sonraki durumun yüklenmesi durum6
durum6:                      //durum6
durum<=durum7;    //sonraki durumun yüklenmesi durum7
durum7:                      //durum7
durum<=durum0;    //sonraki durumun yüklenmesi durum0
endcase

İlk örnekte, lojik 1 değeri için buton(PIN_91) kullanılmıştır, lojik 0 değeri için ise sıfırlama(reset) butonu(PIN_87) kullanılmaktadır.

// sayac, ffffff değerine ulaşırsa ve butona basılırsa
if(sayac==24'hffffff && buton ==0)

Yukarıdaki ifadede butona basılmasını kontrol eden eğer(if) ifadesindeki sayaç değeri, butona basım sürecini sabitleyen bir zaman sabitesidir, sayaç değeri sayesinde butona basım titreşimleri göz ardı edilmiştir.

İkinci örnekte ise, lojik 1 değeri girişi yapan buton kullanılmamış, sadece zaman sabitesi ile durumlar arası geçiş yapılmıştır.

Butona basıldığında lojik 0 sinyali girişe gitmekte, 7 segment display için ise yakılmak istenen segmente ve aktif edilmek istenen displaye ise lojik 0 değeri gönderilmelidir.

Örnek uygulamalarımızda; FPGA çipi olarak ALTERA Firmasının Cyclone IV ailesinden EP4CE6E22C8 model bir FPGA ve 3461BS (4×2 display bloğu) kulandık. Bu FPGA çipinin gelişmiş özellikleri için modelin datasheet’i(bilgiSayfası) incelenmelidir. Ama kabaca olarak kullandığımız FPGA çipi; 6272 Lojik Elementli, 270Kbit Gömülü Hafızası, 91 adet I/O (Giriş/Çıkış) Pini bulunan, 144 ayaklı bir çiptir.

3461bs

ALTERA firmasının üretmiş olduğu FPGA’ları programlayabilmek için, “Quartus” Derleyicisini kullanıyoruz. Quartus Derleyicisinin kurumsal internet sitesinden indirdiğimiz “Demo” versiyonu ile bu örnek uygulamayı gerçekleştirdik.

FPGA’ları programlayabilmek için yaygın olarak kullanılan iki dil; VDHL ve Verilog içerisinden, “C” söz dizimine daha yakın geldiği için “Verilog” ile programlamayı tercih ettik.

FPGA ile Butonlar ve Display arasındaki Pin Bağlantıları :

7segment

butonlar

Sonlu Durum Makinesi Uygulaması Pin Tanımlama & Bağlantıları :

Çıkış Pinleri

LED_A                                                                                        PIN_127

LED_B                                                                                         PIN_126

LED_C                                                                                        PIN_125

LED_D                                                                                         PIN_124

LED_E                                                                                         PIN_121

LED_F                                                                                          PIN_120

LED_G                                                                                        PIN_119

LED_H                                                                                         PIN_115

LED_BIT0                                                                                     PIN_128 (En Sağ Display)

LED_BIT1                                                                                     PIN_129

LED_BIT2                                                                                     PIN_132

LED_BIT3                                                                                     PIN_133

LED_BIT4                                                                                     PIN_135

LED_BIT5                                                                                     PIN_136

LED_BIT6                                                                                     PIN_137

LED_BIT7                                                                                     PIN_138 (En Sol Display)

Giriş Pinleri

saatDarbesi                                                                             PIN_23                        1,2. Uygulama

sifirlama(reset)                                                                       PIN_87                        1,2. Uygulama

buton                                                                                        PIN_91                        1. Uygulama

1.Uygulama: Butona basılması ile 0’dan 7’ye kadar sayan Sonlu Durum Makinesi örnek uygulaması Verilog Program Kodu :

/*******************************************************************************
* @dosya Durum Makinesi(State Machine) Uygulaması
* @yazar Erkan ÇİL
* @sürüm V0.0.1
* @tarih 21-Ağustos-2016
* @özet Cyclone IV EP4CE6 FPGA Durum Makinesi Uygulaması
*
* Bu örnek uygulamada, Cyclone IV EP4CE6 FPGA kartını ile Durum Makinesi
* üretilecek, bu durumlar Display Gösterge üzerinde gösterilecektir edilecektir.
******************************************************************************
*
* Bu program özgür yazılımdır: Özgür Yazılım Vakfı tarafından yayımlanan GNU
* Getkinel Kamu Lisansı’nın sürüm 3 ya da (isteğinize bağlı olarak) daha sonraki
* sürümlerinin hükümleri altında yeniden dağıtabilir ve/veya değiştirebilirsiniz.
*
******************************************************************************/
module durumMakinesi(saatDarbesi,sifirlama,display,etkin,buton);
// durumMakisi MODÜLÜ TANIMI
//-------------Giriş Portları-----------------------------
//saatDarbesi,sifirlama ve buton giriş olarak tanımlanmıştır
input saatDarbesi,sifirlama,buton;
//-------------Çıkış Portları-----------------------------
output[7:0] display; //display Gösterge çıkışı olarak tanımlanmıştır
output[7:0] etkin; //etkinleştirme çıkışı olarak tanımlanmıştır
//-------------Parametre Tanımlamaları--------------------
parameter
durum0=3'b000, //0. durum
durum1=3'b001, //1. durum
durum2=3'b010, //2. durum
durum3=3'b011, //3. durum
durum4=3'b100, //4. durum
durum5=3'b101, //5. durum
durum6=3'b110, //6. durum
durum7=3'b111; //7. durum
//-------------Çıkış Portları Veri Tipleri------------------
// Çıkış portları bellek elemanı(reg-yazmaç) veya bir tel olabilir
reg[2:0] durum; //reg tipindeki durum değişkenin oluşturulması
reg[7:0] display; //reg tipindeki display değişkenin oluşturulması
reg[23:0] sayac; //reg tipindeki sayac değişkenin oluşturulması
reg[7:0] etkin;
//assign etkin=0; // etkinleştirme çıkışına 0 değeri atanmıştır.
//------------Kod Burada Başlamaktadır-------------------------
// Ana döngü bloğu
// Bu sayaç yükselen kenar tetiklemeli olduğundan,
// Bu bloğu saatin yükselen kenarına göre veya sifirlamanın alçalan
// kenarına göre tetikleyeceğiz.
always@(posedge saatDarbesi or negedge sifirlama)
begin
if(!sifirlama) begin //sifirlamaya basılmamışsa
durum<=durum0; //duruma, durum0'ı yükle
sayac<=0; //sayaç değişkenine 0 yükle
end
else begin
sayac<=sayac+1; // sayac değişkeninin içeriğini 1 arttır
// sayac, ffffff değerine ulaşırsa ve butona basılırsa
if(sayac==24'hffffff && buton ==0)
begin
case(durum) //koşula göre durum seçimi
durum0: //durum0
durum<=durum1; //sonraki durumun yüklenmesi durum1
durum1: //durum1
durum<=durum2; //sonraki durumun yüklenmesi durum2
durum2: //durum2
durum<=durum3; //sonraki durumun yüklenmesi durum3
durum3: //durum3
durum<=durum4; //sonraki durumun yüklenmesi durum4
durum4: //durum4
durum<=durum5; //sonraki durumun yüklenmesi durum5
durum5: //durum5
durum<=durum6; //sonraki durumun yüklenmesi durum6
durum6: //durum6
durum<=durum7; //sonraki durumun yüklenmesi durum7
durum7: //durum7
durum<=durum0; //sonraki durumun yüklenmesi durum0
endcase
end
end
end
always@(durum)
begin
case(durum)
durum0: //durum0
begin
display<=8'b1100_0000;//display göstergeye 0 değeri gönderilmesi
etkin<=8'b1111_1110;//1. display gösterge aktif
end
durum1: //durum1
begin
display<=8'b1111_1001;//display göstergeye 1 değeri gönderilmesi
etkin<=8'b1111_1101;//2. display gösterge aktif
end
durum2: //durum2
begin
display<=8'b1010_0100;//display göstergeye 2 değeri gönderilmesi
etkin<=8'b1111_1011;//3. display gösterge aktif
end
durum3: //durum3
begin
display<=8'b1011_0000;//display göstergeye 3 değeri gönderilmesi
etkin<=8'b1111_0111;//4. display gösterge aktif
end
durum4: //durum4
begin
display<=8'b1001_1001;//display göstergeye 4 değeri gönderilmesi
etkin<=8'b1110_1111;//5. display gösterge aktif
end
durum5: //durum5
begin
display<=8'b1001_0010;//display göstergeye 5 değeri gönderilmesi
etkin<=8'b1101_1111;//6. display gösterge aktif
end
durum6: //durum6
begin
display<=8'b1000_0010;//display göstergeye 6 değeri gönderilmesi
etkin<=8'b1011_1111;//7. display gösterge aktif
end
durum7: //durum7
begin
display<=8'b1111_1000;//display göstergeye 7 değeri gönderilmesi
etkin<=8'b0111_1111;//8. display gösterge aktif
end
endcase
end
endmodule // durumMakinesi MODÜLÜ SONU
 

Uygulamanın Görseli :

Jpeg

2.Uygulama: 0’dan F’ye kadar zamana bağlı olarak bir sonraki duruma geçen, Sonlu Durum Makinesi örnek uygulaması Verilog Program Kodu :

/*******************************************************************************
* @dosya Durum Makinesi(State Machine) Uygulaması
* @yazar Erkan ÇİL
* @sürüm V0.0.1
* @tarih 21-Ağustos-2016
* @özet Cyclone IV EP4CE6 FPGA Durum Makinesi Uygulaması
*
* Bu örnek uygulamada, Cyclone IV EP4CE6 FPGA kartını ile Durum Makinesi
* üretilecek, bu durumlar Display Gösterge üzerinde gösterilecektir edilecektir.
******************************************************************************
*
* Bu program özgür yazılımdır: Özgür Yazılım Vakfı tarafından yayımlanan GNU
* Getkinel Kamu Lisansı’nın sürüm 3 ya da (isteğinize bağlı olarak) daha sonraki
* sürümlerinin hükümleri altında yeniden dağıtabilir ve/veya değiştirebilirsiniz.
*
******************************************************************************/
module durumMakinesi(saatDarbesi,sifirlama,display,etkin);
// durumMakisi MODÜLÜ TANIMI
//-------------Giriş Portları-----------------------------
input saatDarbesi,sifirlama; //saatDarbesi,sifirlama giriş olarak tanımlanmıştır
//-------------Çıkış Portları-----------------------------
output[7:0] display; //display Gösterge çıkışı olarak tanımlanmıştır
output[7:0] etkin; //etkinleştirme çıkışı olarak tanımlanmıştır
//-------------Parametre Tanımlamaları--------------------
parameter
durum0=4'b0000, //0. durum
durum1=4'b0001, //1. durum
durum2=4'b0010, //2. durum
durum3=4'b0011, //3. durum
durum4=4'b0100, //4. durum
durum5=4'b0101, //5. durum
durum6=4'b0110, //6. durum
durum7=4'b0111, //7. durum
durum8=4'b1000, //0. durum
durum9=4'b1001, //1. durum
durumA=4'b1010, //2. durum
durumB=4'b1011, //3. durum
durumC=4'b1100, //4. durum
durumD=4'b1101, //5. durum
durumE=4'b1110, //6. durum
durumF=4'b1111; //7. durum
//-------------Çıkış Portları Veri Tipleri------------------
// Çıkış portları bellek elemanı(reg-yazmaç) veya bir tel olabilir
reg[3:0] durum; //reg tipindeki durum değişkenin oluşturulması
reg[7:0] display; //reg tipindeki display değişkenin oluşturulması
reg[25:0] sayac; //reg tipindeki sayac değişkenin oluşturulması
reg[7:0] etkin;
//assign etkin=0; // etkinleştirme çıkışına 0 değeri atanmıştır.
//------------Kod Burada Başlamaktadır-------------------------
// Ana döngü bloğu
// Bu sayaç yükselen kenar tetiklemeli olduğundan,
// Bu bloğu saatin yükselen kenarına göre veya sifirlamanın alçalan
// kenarına göre tetikleyeceğiz.
always@(posedge saatDarbesi or negedge sifirlama)
begin
if(!sifirlama) begin //sifirlamaya basılmamışsa
durum<=durum0; //duruma, durum0'ı yükle
sayac<=0; //sayaç değişkenine 0 yükle
end
else begin
sayac<=sayac+1; // sayac değişkeninin içeriğini 1 arttır
if(sayac==26'h3ffffff) // sayac, 3ffffff değerine ulaşırsa
begin
case(durum) //koşula göre durum seçimi
durum0: //durum0
durum<=durum1; //bir sonraki durumun yüklenmesi durum1
durum1: //durum1
durum<=durum2; //bir sonraki durumun yüklenmesi durum2
durum2: //durum2
durum<=durum3; //bir sonraki durumun yüklenmesi durum3
durum3: //durum3
durum<=durum4; //bir sonraki durumun yüklenmesi durum4
durum4: //durum4
durum<=durum5; //bir sonraki durumun yüklenmesi durum5
durum5: //durum5
durum<=durum6; //bir sonraki durumun yüklenmesi durum6
durum6: //durum6
durum<=durum7; //bir sonraki durumun yüklenmesi durum7
durum7: //durum7
durum<=durum8; //bir sonraki durumun yüklenmesi durum0
durum8: //durum0
durum<=durum9; //bir sonraki durumun yüklenmesi durum1
durum9: //durum1
durum<=durumA; //bir sonraki durumun yüklenmesi durum2
durumA: //durum2
durum<=durumB; //bir sonraki durumun yüklenmesi durum3
durumB: //durum3
durum<=durumC; //bir sonraki durumun yüklenmesi durum4
durumC: //durum4
durum<=durumD; //bir sonraki durumun yüklenmesi durum5
durumD: //durum5
durum<=durumE; //bir sonraki durumun yüklenmesi durum6
durumE: //durum6
durum<=durumF; //bir sonraki durumun yüklenmesi durum7
// durumF: //durum7
// durum<=durum0; //bir sonraki durumun yüklenmesi durum0
endcase
end
end
end
always@(durum)
begin
case(durum)
durum0: //durum0
begin
display<=8'b1100_0000;//display göstergeye 0 değeri gönderilmesi
etkin<=8'b1111_1110;//1. display gösterge aktif
end
durum1: //durum1
begin
display<=8'b1111_1001;//display göstergeye 1 değeri gönderilmesi
etkin<=8'b1111_1101;//2. display gösterge aktif
end
durum2: //durum2
begin
display<=8'b1010_0100;//display göstergeye 2 değeri gönderilmesi
etkin<=8'b1111_1011;//3. display gösterge aktif
end
durum3: //durum3
begin
display<=8'b1011_0000;//display göstergeye 3 değeri gönderilmesi
etkin<=8'b1111_0111;//4. display gösterge aktif
end
durum4: //durum4
begin
display<=8'b1001_1001;//display göstergeye 4 değeri gönderilmesi
etkin<=8'b1110_1111;//5. display gösterge aktif
end
durum5: //durum5
begin
display<=8'b1001_0010;//display göstergeye 5 değeri gönderilmesi
etkin<=8'b1101_1111;//6. display gösterge aktif
end
durum6: //durum6
begin
display<=8'b1000_0010;//display göstergeye 6 değeri gönderilmesi
etkin<=8'b1011_1111;//7. display gösterge aktif
end
durum7: //durum7
begin
display<=8'b1111_1000;//display göstergeye 7 değeri gönderilmesi
etkin<=8'b0111_1111;//8. display gösterge aktif
end
durum8: //durum8
begin
display<=8'b1000_0000;//display göstergeye 0 değeri gönderilmesi
etkin<=8'b0111_1111;//1. display gösterge aktif
end
durum9: //durum9
begin
display<=8'b1001_0000;//display göstergeye 1 değeri gönderilmesi
etkin<=8'b1011_1111;//2. display gösterge aktif
end
durumA: //durumA
begin
display<=8'b1000_1000;//display göstergeye 2 değeri gönderilmesi
etkin<=8'b1101_1111;//3. display gösterge aktif
end
durumB: //durumB
begin
display<=8'b1000_0011;//display göstergeye 3 değeri gönderilmesi
etkin<=8'b1110_1111;//4. display gösterge aktif
end
durumC: //durumC
begin
display<=8'b1100_0110;//display göstergeye 4 değeri gönderilmesi
etkin<=8'b1111_0111;//5. display gösterge aktif
end
durumD: //durumD
begin
display<=8'b1010_0001;//display göstergeye 5 değeri gönderilmesi
etkin<=8'b1111_1011;//6. display gösterge aktif
end
durumE: //durumE
begin
display<=8'b1000_0110;//display göstergeye 6 değeri gönderilmesi
etkin<=8'b1111_1101;//7. display gösterge aktif
end
durumF: //durumF
begin
display<=8'b1000_1110;//display göstergeye 7 değeri gönderilmesi
etkin<=8'b0000_0000;//8. display gösterge aktif
end
endcase
end
endmodule // durumMakinesi MODÜLÜ SONU

Uygulamanın Görseli :

Jpeg

Uygulamanın Videosu :

Uygulamanın PDF Dosyasını indirmek için: 

İndir (PDF, 1.61MB)

, , ,

  1. Henüz hiç yorum yok.
(yayınlanmayacak)