FPGA ile (Sahada Programlanabilir Mantık Dizeleri) gerçekleştirilen bu örnek uygulamamızda deneme kartımız üzerinde bulunan 8 adet (4×2 display bloğu) 7 segment display ile 2 örnek uygulama yapacağız.

İlk örnek uygulamamızda bu sekiz display de, “7,6,5,4,3,2,1,0” rakam değerlerini sırası ile yazdıracağız.

İkinci  örnek uygulamamızda ise 0 ile 9999 arasında sürekli dönen bir sayıcı gerçekleştireceğiz.

Uygulamaların açıklamaları, komut satırlarının yanında yorum olarak yapılmıştır. Yorumlar dikkatli okunduğunda programların çalışma algoritması anlaşılmaktadır.
Örnek uygulamalarımızda; FPGA çipi olarak ALTERA Firmasının Cyclone IV ailesinden EP4CE6E22C8 model bir FPGA ve 3461BS ortak anotlu(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 ve Display arasındaki Pin Bağlantıları :

pin baglanti

Display Kontrol Uygulaması Pin Tanımlama & Bağlantıları :
Çıkış Pinleri
etkin[0] >>PIN_128
etkin[1] >>PIN_129
etkin[2] >>PIN_132
etkin[3] >>PIN_133
etkin[4] >>PIN_135
etkin[5] >>PIN_136
etkin[6] >>PIN_137
veriCikisi[0] >>PIN_127
veriCikisi[1] >>PIN_126
veriCikisi[2] >>PIN_125
veriCikisi[3] >>PIN_124
veriCikisi[4] >>PIN_121
veriCikisi[5] >>PIN_120
veriCikisi[6] >>PIN_119
veriCikisi[7] >>PIN_115
Giriş Pinleri
PIN_23 << saatDarbesi
PIN_87 << saatDarbesi

Display Kontrol Uygulaması Program Kodu :

/*******************************************************************************
* @dosya LCD Uygulaması
* @yazar Erkan ÇİL
* @sürüm V0.0.1
* @tarih 13-Temmuz-2016
* @özet Cyclone IV EP4CE6 FPGA Yedi Segment Display Kontrol Uygulaması
*
* Bu örnek uygulamada, Cyclone IV EP4CE6 FPGA kartını ile 3461BS display kullanılarak
* “7,6,5,4,3,2,1,0” rakam değerlerini sırası gösterilecektir.
******************************************************************************
*
* Bu program özgür yazılımdır: Özgür Yazılım Vakfı tarafından yayımlanan GNU
* Genel 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 yediSegDisplay (saatDarbesi,reset,veriCikisi,etkin);
// yedi segment display(yediSegDisplay) MODÜLÜ TANIMI
//-------------Giriş Portları-----------------------------
input saatDarbesi,reset; //50mHz saatDarbesi ve giriş olarka tanımlanması
//-------------Çıkış Portları-----------------------------
output[7:0] veriCikisi; //veriCikisi çıkış olarak tanımlanması
output[7:0] etkin; //etkinleştirme çıkış olarak tanımlanması
//-------------Çıkış Portları Veri Tipleri------------------
// Çıkış portları bellek elemanı(reg-yazmaç) veya bir tel olabilir
reg[7:0] veriCikisi; //veriCikisi registerinin oluşturulması
reg[7:0] etkin; //etkinkeştirme registerinin oluşturulması
reg[15:0] sayacTarama; //sayacTarama registerinin oluşturulması
reg[4:0] veriCikisi_buf; //veriCikisi_buf registerinin oluşturulması
//------------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 veya,
// reset butonun alçalan kenarına göre tetikleyeceğiz.
always@(posedge saatDarbesi or negedge reset)
begin
if(!reset) begin // reset e basılmazsa döngüye başla
sayacTarama<=0; // 0 değerinin sayacTarama registerine aktarılması
end
else begin
sayacTarama<=sayacTarama+1; //sayacTarama registerininin içeriğini 1 arttır
end
end
always @(sayacTarama)
begin
case(sayacTarama[15:13])
// sayacTarama[15:13] registerinin sırası ile taranması
3'b000 :
etkin = 8'b1111_1110; // 0. Displayin taranması
3'b001 :
etkin = 8'b1111_1101; // 1. Displayin taranması
3'b010 :
etkin = 8'b1111_1011; // 2. Displayin taranması
3'b011 :
etkin = 8'b1111_0111; // 3. Displayin taranması
3'b100 :
etkin = 8'b1110_1111; // 4. Displayin taranması
3'b101 :
etkin = 8'b1101_1111; // 5. Displayin taranması
3'b110 :
etkin = 8'b1011_1111; // 6. Displayin taranması
3'b111 :
etkin = 8'b0111_1111; // 7. Displayin taranması
default :
etkin = 8'b1111_1110; // Default durum tanımı
endcase
end
// Displaylerin sırası ile aktif hale getirilmesi
always@(etkin)
begin
case(etkin) //etkinleştirme registerinin taranması
8'b1111_1110:
veriCikisi_buf=0; // 0. Display Segmentinin enable edilmesi
8'b1111_1101:
veriCikisi_buf=1; // 1. Display Segmentinin enable edilmesi
8'b1111_1011:
veriCikisi_buf=2; // 2. Display Segmentinin enable edilmesi
8'b1111_0111:
veriCikisi_buf=3; // 3. Display Segmentinin enable edilmesi
8'b1110_1111:
veriCikisi_buf=4; // 4. Display Segmentinin enable edilmesi
8'b1101_1111:
veriCikisi_buf=5; // 5. Display Segmentinin enable edilmesi
8'b1011_1111:
veriCikisi_buf=6; // 6. Display Segmentinin enable edilmesi
8'b0111_1111:
veriCikisi_buf=7; // 7. Display Segmentinin enable edilmesi
default:
veriCikisi_buf=8; // Default durum tanımı
endcase
end
// Displaylerin rakam segment datasının dönderilmesi
always@(veriCikisi_buf)
begin
case(veriCikisi_buf) //DP-G-F-E-D-C-B-A
4'b0000:
veriCikisi=8'b1100_0000; //0
4'b0001:
veriCikisi=8'b1111_1001; //1
4'b0010:
veriCikisi=8'b1010_0100; //2
4'b0011:
veriCikisi=8'b1011_0000; //3
4'b0100:
veriCikisi=8'b1001_1001; //4
4'b0101:
veriCikisi=8'b1001_0010; //5
4'b0110:
veriCikisi=8'b1000_0010; //6
4'b0111:
veriCikisi=8'b1111_1000; //7
default:
veriCikisi=8'b1000_0000; // Default durum tanımı
endcase
end
endmodule // yedi segment Display(yediSegDisplay) MODÜLÜ SONU

Display Kontrol Uygulaması Görseli :

Jpeg

Yedi Segment (0-9999) Sayıcı Uygulaması Pin Tanımlama & Bağlantıları :
Çıkış Pinleri
a >>PIN_127
an[0] >>PIN_128
an[1] >>PIN_129
an[2] >>PIN_132
an[3] >>PIN_133
an[4] >>PIN_135
an[5] >>PIN_136
an[6] >>PIN_137
an[7] >>PIN_138
b >>PIN_126
c >>PIN_125
d >>PIN_124
dp >>PIN_115
e >>PIN_121
f >>PIN_120
g >>PIN_119
Giriş Pinleri
PIN_23 << saatDarbesi
PIN_87 << saatDarbesi

Yedi Segment (0-9999) Sayıcı Uygulaması Program Kodu :

/*******************************************************************************
* @dosya LCD Uygulaması
* @yazar Erkan ÇİL
* @sürüm V0.0.1
* @tarih 13-Temmuz-2016
* @özet Cyclone IV EP4CE6 FPGA Yedi Segment Sayici Uygulaması
*
* Bu örnek uygulamada, Cyclone IV EP4CE6 FPGA kartını ile 3461BS display kullanılarak
* 0-9999 rakamları arası sayan bir sayıcı üretilecektir.
******************************************************************************
*
* Bu program özgür yazılımdır: Özgür Yazılım Vakfı tarafından yayımlanan GNU
* Genel 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 yediSegSayici( // yedi segment sayıcı(yediSegSayici) MODÜLÜ TANIMI
//-------------Giriş Portları-----------------------------
input saatDarbesi, // clock girişi
input reset, // reset girişi
//-------------Çıkış Portları-----------------------------
output a, // a segmenti çıkışı
output b, // b segmenti çıkışı
output c, // c segmenti çıkışı
output d, // d segmenti çıkışı
output e, // e segmenti çıkışı
output f, // f segmenti çıkışı
output g, // g segmenti çıkışı
output dp, // nokta segmenti çıkışı
output [7:0]an // tarama çıkışı
);
//-------------Çıkış Portları Veri Tipleri------------------
// Çıkış portları bellek elemanı(reg-yazmaç) veya bir tel olabilir
reg [3:0]basamak1; // basamak1 hanesi yazmacı
reg [3:0]basamak2; // basamak2 hanesi yazmacı
reg [3:0]basamak3; // basamak3 hanesi yazmacı
reg [3:0]basamak4; // basamak3 hanesi yazmacı
reg [22:0] gecikmeSuresi; //gecikme/bekleme süresi yazmacı
wire test; // test bağlantısı
//------------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 veya,
// reset butonun alçalan kenarına göre tetikleyeceğiz.
always @ (posedge saatDarbesi or negedge reset)
begin
if (!reset) //reset e basılılırsa
gecikmeSuresi <= 0; // gecikmeSuresi ne 0 değeri yükle
else
gecikmeSuresi <= gecikmeSuresi + 1; // gecikmeSuresi nin değerini 1 arttır
end
// test atamasının tanımlanması
assign test = &gecikmeSuresi;
// gecikmeSuresi nin her bit inin kendisi ile VE işlemi uygulanması; gecikmeSuresi nin her biti 1 olduğunda test değeri de 1 olacak
always @ (posedge test or negedge reset)
begin
if (!reset) begin
basamak1 <= 0; //birler basamağına 0 değerinin yüklenmesi
basamak2 <= 0; //onlar basamağına 0 değerinin yüklenmesi
basamak3 <= 0; //yüzler basamağına 0 değerinin yüklenmesi
basamak4 <= 0; //binler basamağına 0 değerinin yüklenmesi
end
/*------------------------------------------------*/
else if (basamak1==4'd9)
begin //birler basamağında 9 değerine ulaşılırsa
basamak1 <= 0; //birler basamağına 0 değerinin yüklenmesi
if (basamak2 == 4'd9) //onlar basamağında 9 değerine ulaşılırsa
basamak2 <= 0; //onlar basamağına 0 değerinin yüklenmesi
/*------------------------------------------------*/
if (basamak2==4'd9 && basamak1==4'd9)
begin //99 değerine ulaşılırsa
basamak2 <= 0 && basamak1 <= 0; //xx00 değerinin yüklenmesi
if (basamak3 == 4'd9) //yüzler basamağında 9 değerine ulaşılırsa
basamak3 <= 0; //yüzler basamağına 0 değerinin yüklenmesi
/*------------------------------------------------*/
if (basamak3==4'd9 && basamak2==4'd9 && basamak1==4'd9)
begin //999 değerine ulaşılırsa
basamak3 <= 0 && basamak2 <= 0 && basamak1 <= 0; //x000 değerinin yüklenmesi
if (basamak4 == 4'd9) //binler basamağında 9 değerine ulaşılırsa
basamak4 <= 0; //binler basamağına 0 değerinin yüklenmesi
else
basamak4 <= basamak4 + 1; //binler basamağı değerinin 1 arttırılması
end
/*------------------------------------------------*/
else
basamak3 <= basamak3 + 1; //yüzler basamağı değerinin 1 arttırılması
end
/*------------------------------------------------*/
else
basamak2 <= basamak2 + 1; //onlar basamağı değerinin 1 arttırılması
end
/*------------------------------------------------*/
else
basamak1 <= basamak1 + 1; //birler basamağı değerinin 1 arttırılması
end
//Display Segmentlerinin Taranması
localparam N = 18; // Parametre tanımlanması
reg [N-1:0]sayac; // sayac yazmacının oluşturulması
always @ (posedge saatDarbesi or negedge reset)
begin
if (!reset) // reset e basılılırsa
sayac <= 0;
else
sayac <= sayac + 1; // sayac degerini bir arttir
end
reg [6:0]yediSegment; // yediSegment yazmacının oluşturulması
reg [7:0]etkinTarama; // etkinTarama yazmacının oluşturulması
always @ (*)
begin
case(sayac[15:13])
// sayac[15:13] registerinin sırası ile taranması
3'b000 :
begin
yediSegment = basamak1;
etkinTarama = 8'b1111_1110; // 0. Displayin taranması
end
3'b001 :
begin
yediSegment = basamak2;
etkinTarama = 8'b1111_1101; // 1. Displayin taranması
end
3'b010 :
begin
yediSegment = basamak3;
etkinTarama = 8'b1111_1011; // 2. Displayin taranması
end
3'b011 :
begin
yediSegment = basamak4;
etkinTarama = 8'b1111_0111; // 3. Displayin taranması
end
3'b100 :
begin
yediSegment = 6'ha;
etkinTarama = 8'b1110_1111; // 4. Displayin taranması
end
3'b101 :
begin
yediSegment = 6'ha;
etkinTarama = 8'b1101_1111; // 5. Displayin taranması
end
3'b110 :
begin
yediSegment = 6'ha;
etkinTarama = 8'b1011_1111; // 6. Displayin taranması
end
3'b111 :
begin
yediSegment = 6'ha;
etkinTarama = 8'b0111_1111; // 7. Displayin taranması
end
default :
begin
yediSegment = 6'ha;
etkinTarama = 8'b1111_1110; // Default durum tanımı
end
endcase
end
assign an = etkinTarama; // an içerine etkinTarama değerinin tanımlanması
reg [6:0] yediSegment_gecici; // yediSegment_gecici yazmacının oluşturulması
always @ (*)
begin
case(yediSegment)
4'd0 : yediSegment_gecici = 7'b1000000; //0 rakamı oluşturulması
4'd1 : yediSegment_gecici = 7'b1111001; //1 rakamı oluşturulması
4'd2 : yediSegment_gecici = 7'b0100100; //2 rakamı oluşturulması
4'd3 : yediSegment_gecici = 7'b0110000; //3 rakamı oluşturulması
4'd4 : yediSegment_gecici = 7'b0011001; //4 rakamı oluşturulması
4'd5 : yediSegment_gecici = 7'b0010010; //5 rakamı oluşturulması
4'd6 : yediSegment_gecici = 7'b0000010; //6 rakamı oluşturulması
4'd7 : yediSegment_gecici = 7'b1111000; //7 rakamı oluşturulması
4'd8 : yediSegment_gecici = 7'b0000000; //8 rakamı oluşturulması
4'd9 : yediSegment_gecici = 7'b0010000; //9 rakamı oluşturulması
default : yediSegment_gecici = 7'b0111111; //nokta
endcase
end
assign {g, f, e, d, c, b, a} = yediSegment_gecici;
assign dp = 1'b1; // display noktalari SÖNÜK hale getiriliyor
endmodule // yedi segment sayıcı(yediSegSayici) MODÜLÜ SONU

Yedi Segment (0-9999) Sayıcı Uygulaması Görseli :

sayici

FPGA ile Display Kontrol ve (0-9999) Sayıcı Uygulaması PDF Dosyası :

İndir (PDF, 1.36MB)