Picproje Elektronik Sitesi

DİJİTAL & ANALOG ELEKTRONİK => Pld, Spld, Pal, Gal, Cpld, Fpga => Konuyu başlatan: Mucit23 - 28 Şubat 2017, 11:19:45

Başlık: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 28 Şubat 2017, 11:19:45
Selamlar,

PSOC üzerinde Verilog Öğrenmeye çalışıyorum. Şuanda temel işlemleri öğrendim sayılır ama karmaşık işlemlerde hala mantık yürütemiyorum.

İleride lazım olacağı için SPI mantığını verilog da yapmaya çalışıyorum. Tek kanal basitçe 8 bitlik veriyi seri olarak dışarı çıkartan bir spi bloğu yazmaya çalışıyorum.

Bunun için bir verilog dosyası oluşturdum. Girişleri çıkışları tanımladım. Veri girişi için psoc'a özel komutlarla bir adres tanımladım. Bundan sonra tıkandım kaldım.

`include "cypress.v"
//`#end` -- edit above this line, do not edit this line
// Generated on 02/28/2017 at 10:07
// Component: ParalelToSerial
module ParalelToSerial (
output  CLKOUT,
output  DOUT,
input   CLKIN
);

//`#start body` -- edit after this line, do not edit this line
    reg clk_count,count_start;
    wire dout=0;
    wire clkout=0;
   
   
    wire [7:0] control_reg_out;
    assign DOUT = dout;
    assign CLKOUT = clkout;

    cy_psoc3_control #(.cy_init_value (8'b00000000), .cy_force_order(`TRUE)) //Default mode
    myControlReg(.control(control_reg_out));
   
    always @ (posedge CLKIN)
    begin
   
    end
   
//`#end` -- edit above this line, do not edit this line
endmodule


Buradaki kodlar içerisinde aşağıdaki kodlarla bir kontrol registeri tanımlıyorum. Bu register ile C tarafından Verilog tarafına veri aktarabiliyorum. Bir adres gibi düşünün. C tarafında bu adrese bir veri yazınca Veri doğrudan Verilog tarafında kullanılabiliyor. Yani control_reg_out değişkenim benim dışarıya seri olarak aktarılacak olan verim.

Bundan sonra clock sinyalinin her bir yükselen kenarında veriyi sıra ile dışarı aktarım çıkışta clock sinyali üretmem lazım. Burada takıldım.
Örnek SPI kodlarını inceliyorum ama bir sürü kontrol var. Anlaşılır bir kod bulamadım.

Bu konuda yardımcı olabilecek olan varmı? Bundan sonra nasıl yapmam gerekiyor? Veriyi nasıl seri olarak göndereceğim? Aynı zamanda clock sinyali nasıl üreteceğim?

Verilog veya VHDL bilen kimler var?
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: furkanyx - 28 Şubat 2017, 14:25:55
Aşağıda linkini verdiğim konu başlığında spi kodunu paylaşmıştım.
https://www.picproje.org/index.php/topic,68764.msg528241.html#msg528241
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 28 Şubat 2017, 14:55:09
@furkanyx Hocam o kodu inceledim. Çok karmaşık işin içinden çıkamadım.

Ben anlamak için kodu kendim yazayım diyorum. Son derece basit 8 bitlik veriyi clk ile birlikte seri olarak dışarı çıkaran bir verilog programı yazmaya çalışıyorum. Şuanda onunla ilgili çalışıyorum.

Ben bir kod yazdım. status ve control_reg_out adında iki adet değişkenim var. control_reg_out benim gönderilecek verimi saklıyor. Eğer status değişkeninin 0. biti 1 olursa control_reg_out değişkenini Seri olarak dışarı verip status değişkeninin 0. bitini '0' yaptıktan sonra dursun istiyorum. Bunu yapabilirsem geriye kalan teferruatlarıda yapabilirim.

Yazdığım kod aşağıdaki gibi.

`include "cypress.v"
//`#end` -- edit above this line, do not edit this line
// Generated on 02/28/2017 at 10:07
// Component: ParalelToSerial
module ParalelToSerial (
output  CLKOUT,
output  DOUT,
input   CLKIN
);

//`#start body` -- edit after this line, do not edit this line
    reg clk_count;
    reg dout;
    reg clkout;   
    reg [7:0] status;
    reg [7:0] control_reg_out;
   
    assign DOUT = dout;
    assign CLKOUT = clkout;
   
    cy_psoc3_control #(.cy_init_value (8'b00000000), .cy_force_order(`TRUE)) //Default mode
    MyTxReg(.control(control_reg_out));
    cy_psoc3_control #(.cy_init_value (8'b00000000), .cy_force_order(`TRUE)) //Default mode
    MyStatus(.control(status));
       
    always @ (posedge CLKIN)
    begin

       if(status==1'b1)
       begin
         clkout = 0;
         dout=control_reg_out[clk_count];
         clkout = 1;
         
         clk_count = clk_count + 1;
         
         if(clk_count == 8)
         begin
           status = 0;
         end
       end
       else
       begin
          clk_count=0;
          dout=0;
          clkout=0;
       end

    end

//`#end` -- edit above this line, do not edit this line
endmodule


Tabi yukarıdaki kodu çalıştıramadım. Muhtemelen mantık hatası yapıyorum.

Ama basit işlemler yapabiliyorum. Örneğin  status değişkeninin 0. bitine göre dout'a bağlı bir ledi yakıp söndürebiliyorum.

Bu konuda biraz yardımcı olabilirseniz gerisini getirebilirim.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 28 Şubat 2017, 14:59:41
Mesela basitçe bir soru sorayım aklıma gelmişken

Atama işlemlerinde neden eşit ('=') kullanmak yerine küçük eşit ('<=') kullanılıyor?

status <=1'b0 gibi

Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: muhittin_kaplan - 28 Şubat 2017, 15:28:07
Syntax i anlamaya calisma mucit, kabul et.
(Sola ok gibi duruyor)
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: M_B - 28 Şubat 2017, 16:58:38
Alıntı yapılan: Mucit23 - 28 Şubat 2017, 14:59:41
Mesela basitçe bir soru sorayım aklıma gelmişken

Atama işlemlerinde neden eşit ('=') kullanmak yerine küçük eşit ('<=') kullanılıyor?

status <=1'b0 gibi

Hocam konuyu bilmiyorum ama yazdığınız kodta status 1 den kucuk veya eşit demiyormu ?
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 28 Şubat 2017, 17:15:11
Hocam yok incelediğim örneklerde atama işlemleri için kullanılmış.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: superconductor - 28 Şubat 2017, 18:01:05
"<=", non-blocking atama yapar. Üst üste yazdığınız non-blocking atamalar aynı anda diğer bir deyişle paralel işlem görürler.
"=", blocking atama yapar. Sıralı işlem görürler.

Şu site oldukça yararlı: http://www.asic-world.com/tidbits/blocking.html (http://www.asic-world.com/tidbits/blocking.html)
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: furkanyx - 28 Şubat 2017, 19:41:12
Kucukesit ifadesi always blogunun icinde olmasindan kaynakli. Behavioral tasarimlarda atamalar register da tutulmalidir. Non blocking in mantigi bu sekildedir. Registerlarda tutma sebebi de paralel islem yapabilmesindendir. Spi in temel mantigi da clk ile beraber data registerindaki datayi clock polaritesiyle beraber cikisa tek bit aktarmak. Attigim kodda once spi modulune verilen clock bolunerek spi clock u oluşturuyor. Ayni zamana dusen kenar veya yukselen kenari tespit edip flag degerini değiştiriyor. Daha snra data yollamak icin eger ki spiclk ve kenarflag 1 ise shift registerin son bitini cikis registerna yaz yapiyor ve bu islem 8 kere (veya 16 kere tasarima gore degisir) gerçekleştiğinde aktarim tamamlandi flag i aktif edilir. Pek sagliklik bir anlatim olmamis olabilir.  Mobilden anca bu kadar :)
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 28 Şubat 2017, 22:29:20
Yarın yine birkaç deneme yapacağım. Teşekkürler. Küçük eşit mantığını anladım
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 30 Mart 2017, 12:09:32
Selamlar


Verilogdaki şu mantığı çözemedim gitti. Mantığı bi anlasam resmen yürüyecem böyle. Yardıma ihtiyacım var.
Basitçe bir SPI modülü tasarlamaya çalışıyorum. Bir adet status değişkeni birde MyTxReg adında değişkenlerim var
Amacım kısaca şudur. status değişkenim 0x01 olursa MyTxReg içerisindeki 8 bit veriyi spi protoklüne göre dışarı çıkarmak istiyorum.
Bunun için aşağıdaki kodları yazdım.


`include "cypress.v"
//`#end` -- edit above this line, do not edit this line
// Generated on 02/28/2017 at 10:07
// Component: ParalelToSerial
module ParalelToSerial (
output  CLKOUT,
output  DOUT,
input   CLKIN
);


//`#start body` -- edit after this line, do not edit this line
    reg clk_count;
    reg dout;
    reg clkout;   
    reg [7:0] status;
    reg [7:0] control_reg_out;
   
    cy_psoc3_control #(.cy_init_value (8'b00000000), .cy_force_order(`TRUE)) //Default mode
    MyTxReg(.control(control_reg_out));
    cy_psoc3_control #(.cy_init_value (8'b00000000), .cy_force_order(`TRUE)) //Default mode
    MyStatus(.control(status));
       
    always @ (posedge CLKIN)
    begin


       if(status==1'b1)
       begin
         clkout = 0;
         dout=control_reg_out[clk_count];
         clkout = 1;
         
         clk_count = clk_count + 1;
         
         if(clk_count == 8)
         begin
           status = 0;
         end
       end
       else
       begin
          clk_count=0;
          dout=0;
          clkout=0;
       end
    end
       
    assign DOUT = dout;
    assign CLKOUT = clkout;
//`#end` -- edit above this line, do not edit this line
endmodule



Fakat çok problem var. Çalışmıyor. Mantık hatasımı yapıyorum anlayamıyorum. Bu kodu gerçekte denediğimde CLKOUT pininden hiçbirşey çıkmazken DOUT pininden MyTxReg içerisindeki bilgiden bağımsız olarak kare dalga çıkıyor. Kare dalganın frekansı ise Modüle uyguladığım giriş frekansının yarısı, Girişte 1Khz uyguluyorum DOUT'dan 500Hz kare dalga çıkıyor.


Ne alaka anlamıyorum.
Sorun nedir bilgisi olan varmı neyi yanlış yapıyorum? Dediğim gibi bi mantığı anlasam hepsini halledeceğim.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: superconductor - 30 Mart 2017, 12:21:00
Clk_count tek bit tanimli en az 4 bit tanimlaman gerekmez mi ?
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 30 Mart 2017, 14:11:14
Hocam aklım C'ye gidiyor işte. Evet onu düzelttim.
Şuanda  dout=control_reg_out[clk_count]; satırı çalışıyor. control_reg_out içeriğindeki 8 bitlik bilgi seri olarak dışarı veriliyor.

Fakat clock üretemiyorum. Clock nasıl üretirim?
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: superconductor - 30 Mart 2017, 17:36:29
Clockout' u direk clkin'e assign etsen?
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 31 Mart 2017, 10:39:54
hocam selamlar
Olabilir belki ama Transfer tamamlandığımda sistemin  durması gerekiyor. Bu işi yapamadım. Onu nasıl yaparım.
Dediğim gibi Verilog ile ilk defa uğraşıyorum bu yüzden bilgim zayıf.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 05 Nisan 2017, 12:06:03
Hocam hazır kodlara bakıyorum ama çok karmaşık. Genelde hepsi full dublex haberleşme için yazılmış. İncelediğim örneklerde Bir sürü Register'lar vs kontrol edilerek tam anlamıyla bir spi modülü tasarlanmış.  Benim bu kadar kapsamlı bir koda ihtiyacım yok.

Yapmak istediğim kısaca şudur.
Enable girişinden bir start sinyali gelince paralel girişteki 8 bitlik datayı SPI formatında clock ve Data pini ile seri olarak dışarı çıkarıp beklesin yeter. Bunu yapmaya çalışıyorum.

Clock üretmede problem yaşıyorum.
Normalde Clock girişinin Düşen kenarında datanın n. bitini dışarı vermem gerekiyor. Bunu yapıyorum. Daha sonra Clock girişinin Yükselen kenarında Clock çıkışını 1 yapmam gerekiyor. İşte burada takılıyorum. Clock üretme işlemini veri gönderirken yapmam gerekiyor. Ama bunu bir türlü yapamadım.

Sadece yöntem gösterseniz yeterli benim için.




Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: superconductor - 06 Nisan 2017, 10:51:10
Hocam Deo-Nano kit üzerindeki adc chipi bu şekilde okuyorum bir inceleyin istediğiniz bu şekilde bir yapı olmalı. DIN pini ile 3 bit kanal seçimi gidiyor. DB etiketliler adc den gelen datalar.
[IMG]http://i65.tinypic.com/kdtthu.png[/img]


module adcController(clk, chnSel, data, cs, mosi, miso);

input clk;
input [2:0]chnSel;
input miso;

output cs;
reg cs;
output mosi;
reg mosi;

output [11:0]data;
reg [11:0]data;

initial
begin
cs <= 0;
mosi <= 0;
end

reg [7:0]divider;


always @(negedge clk)
begin

if(divider == 0)
begin
cs <= 0;
end

if(divider > 1 && divider < 5)
begin
mosi <= chnSel[divider-2];
end

if(divider >= 5)
begin
mosi <= 0;
data[divider - 5] <= miso;

end

if(divider == 20)
begin
divider <= 0;
cs <= 1;
end
else
begin
divider <= divider + 1;
end

end
endmodule


kod içinde clk üretmedim chipin clk girişi ile adccontroller modülüne giren clk aynı hatta bağlı. İsterseniz clkOut diye bir output oluşturup clk girişine assign edebilirsiniz.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 06 Nisan 2017, 13:55:25
Benzer bir işi bende yaptım ama clock işini çözemedim sadece. Bendeki sistemde clock sinyalinin herzaman çıkmaması lazım. Shift register üzerinde kullanıcam bunu. Bu yüzden Data ile birlikte Clock sinyali çıkması gerekiyor. Diğer türlü boş data içeri alınabilir.
İşin mantığını biraz biraz anlamaya başladım. Şu clock işinide çözersem tamamdır.

@superconductor hocam bir şarta bağlı olarak Clock girişini Clock çıkışına nasıl eşitlerim.
assign etme işlemini doğrudan if içerisinde yaparsam hata veriyor.
Birde bunu bi always bloğu içerisine almak gerekiyor. Bunu nasıl yapmam lazım?
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 06 Nisan 2017, 17:29:12
Verilog işi biraz biraz oturmaya başladı ama hala anlamadığım birçok nokta var.

Şuanda istediğimi yapmak üzereyim. Bir hata alıyorum sebebini tahmin ettiğim şeymi anlamaya çalışıyorum.

Sorum şudur.
İki farklı always bloğu olsun.

İki bloktada ortak olarak kullanılan reg tipi değişken olunca berleyici bana "Can't handle registered multi driver" hatası veriyor. Hatanın anlamı anladığım kadarıyla şudur. Aynı değişkenler iki farklı blokta kullanılıyor. Burada işlemler paralel olarak yapıldığı için aynı anda iki bloktada aynı registere müdahale etme gibi bir olasılık var. Bu durumdan dolayı derleyici hata veriyor. Doğrumudur sizce? Bu durumu nasıl aşarım?

Şuanda aşağıdaki gibi bir kod yazdım.
module ParalelToSerial (
output  Busy,
output  Clkout,
output  Dout,
input   Clkin,
input [7:0]Din,
input   En
);

//`#start body` -- edit after this line, do not edit this line
    reg busy;
    reg tx_en;
    reg dout;
    reg clkout;   
    reg [3:0]cnt_spi;
   
    always @ (posedge Clkin)
    begin
       if (En == 1'b1)
       begin
         tx_en <= 1'b1;
         busy <= 1'b1;
       end
       
    end
   
   
    always @ (negedge Clkin)
    begin   
       if(tx_en == 1'b1)
       begin
         clkout <= Clkin;
       end
       
       if(tx_en == 1'b1)
       begin       
            dout <= Din[cnt_spi];
            cnt_spi <= cnt_spi + 1;
       end
       
       if(cnt_spi==8)  //aktarım tamamlandı
       begin
         busy <= 1'b0;
         tx_en <= 1'b0;
       end
    end

    assign Busy = busy;
    assign Dout = dout;
    assign Clkout = clkout;

endmodule


2. Sorum assign ile yaptığım atama işlemleri always bloğunun içerisinde kullanılabiliyormu? Eğer kullanılamıyorsa yazdığım programın başına veya sonuna yazmam farkedermi?

3. Sorum Bazı uygulamalarda aşağıdaki gibi işlemler görüyorum

Data <= {Data[6:0], 1'b0};

Data 8 bitlik reg tipi değişken. Burada ne yapılmış olabilir? Güzel parantez içerisindeki işlemi anlayamadım.

Dediğim gibi yapı kafamda bi otursa yürüyecem. Bu tür soruları anlayamıyorum.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: muuzoo - 06 Nisan 2017, 22:12:34
Verilog uzmanlık alanım değil ama VHDL'den yola çıkarak yorumlarsak,

1) tx_en ve busy sinyalini iki farklı noktadan ve biri yükselen kenarda diğeri ise düşen kenarda değiştirmeye kalkmışsınız. Böyle bir kullanıma kızar sentezleyiciler. Çoğu durumda özel register yapıları hariç çift kenar tetiklemeye izin vermezler. Hatanızın sebebi aynı kaynağı iki farklı noktadan değer atamaya çalışıyorsunuz. Multiple driver hatasının sebebi o. İki farklı always bloğu içinden değer değiştirmeye çalışmışsınız.

2) verilog bilgim fazla değil, sadece tahminen bu atama VHDL deki sinyal ataması gibi o yüzden yine tahmini olarak bir sorun olmaaması lazım nerede yazarsanız yazın.

3) O işlem sola kaydırma işlemi olarak yorumlanabilir. 8 bitlik verinin en son 7 bitini alıp [6 :0]  sonuna 0 eklerseniz veriyi sola kaydırmış olursunuz. Bu işlem o işe yarıyor. Yani shift işlemi.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 07 Nisan 2017, 11:07:57
@muzoo

hocam sonuca baya yaklaştım. Cevabınız için teşekkür ederim.

Clock ile ilgili problemim devam ediyor onu çözersem hedefime ulaşmış olacağım.

Tasarladığım modül'de enable girişine bir adet buton bağladım. Butona basınca sisteme 0 gidiyor
modülün içindeki verilog kodum aşağıdaki gibi
module ParalelToSerial (
output  Busy,
output  Clkout,
output  Dout,
input   Clkin,
input [7:0]Din,
input   En
);

//`#start body` -- edit after this line, do not edit this line
    reg busy;
    reg tx_en;
    reg dout;
    reg clkout;   
    reg [3:0]cnt_spi;
   
    initial begin
      clkout <= 1'b0;
      dout <= 1'b0;
      busy <= 1'b0;
      tx_en <= 1'b0;
      cnt_spi <= 1'b0;
    end
   
    always @ (posedge Clkin)
    begin
       if(tx_en == 1'b1)
       begin
         clkout <= Clkin;
       end
    end
   
    always @ (negedge Clkin)
    begin 
       if (En == 1'b0 && busy == 1'b0)
       begin
         tx_en <= 1'b1;
         busy <= 1'b1;
       end
       
       if(tx_en == 1'b1)
       begin       
            dout <= Din[cnt_spi];
            cnt_spi <= cnt_spi + 1;
       end
       
       if(cnt_spi==8)  //aktarım tamamlandı
       begin
         cnt_spi <= 1'b0;
         busy <= 1'b0;
         tx_en <= 1'b0;
       end
    end

    assign Busy = busy;
    assign Dout = dout;
    assign Clkout = clkout;
   
//`#end` -- edit above this line, do not edit this line
endmodule


Data çıkışı açıkçası tam istediğim gibi çalışıyor. Butona bastığım sürece Paralel girişimdeki data seri olarak dışarı çıkıyor. Bunu Osiloskopta görebiliyorum.
Yalnız clock çıkışı olmadı.

always bloğu içerisinde clock çıkışı üretemiyorum.

Bunu farklı bir yöntemle yapmam lazım. Bu konuda önerilerinize açığım.

Bir Sorum olacak. internette always bloğunun yapısını incelerken aşağıdaki gibi bir kullanım gördüm birkaç yerde
always @ (*)

şart kısmına yıldız koymak ne anlama geliyor? Bu yapı PSoC editörümdeki verilog derleyicisinde çalışmıyor. Sentezleme aşamasında hata veriyor.  Bu kullanım VHDL içinmi geçerli? Nasıl çalışıyor?
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: superconductor - 07 Nisan 2017, 12:39:25
Hocam enable girişi ile clock sinyalini AND' leyip, always bloğu dışında clockOut' a assign etmeyi denermisiniz.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 07 Nisan 2017, 13:56:54
Hocam evet oldu şimdi. Aklıma gelmiyor nedense AND işlemi.

Koduda biraz düzenledim.

dout <= Din[cnt_spi]; Bu işlemi yaparken data nedense 2 clock palsinden sonra gelmeye başlıyordu. Şimdi bir tane tx_buf tanımlayıp veriyi aşağıdaki kod ile shift ederek gönderiyorum.

tx_buf <= {tx_buf[6:0], 1'b0};

Bu şekilde yaptığım zaman tam olarak standart spi formatında çıktı aldım.
(https://s10.postimg.cc/siy435gh5/Ekran_Al_nt_s.jpg)

1. kanal data (0xAA)
2. kanal clock
3. kanal busy

Sıkıntı yok gibi görünüyor. Şimdi biraz yazılımı düzenlemem lazım.

Verilog ile ilgili bir soru sorayım.

tx_buf <= {tx_buf[6:0], 1'b0};

Bu satırda nasıl sihft yapıldığını anlayamadım.  {} ile ne gibi kullanımlar verilog'da. Bunlar ne diye geçer nasıl öğrenebilirim?
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: muuzoo - 07 Nisan 2017, 15:32:37
@Mucit23

Alıntı Yap
tx_buf <= {tx_buf[6:0], 1'b0};

Bu satırda nasıl sihft yapıldığını anlayamadım.  {} ile ne gibi kullanımlar verilog'da. Bunlar ne diye geçer nasıl öğrenebilirim?

Mantık çok basit. Diyelim ki verimiz şu olsun "1100 0000"

1) tx_buf[6:0] ile ilgili verinin en son 7 bitini seçtik. Yani "100 0000"
2){} işareti birleştirme operatorü olarak yorumlanabilir "concatenation" işlemi. {tx_buf[6:0],1'b0} diyerek aslında {1000000,0} verisini birleştir demiş oldunuz.
3 Yeni değerimiz "1000 0000" oldu. Görüdğünüz gibi veriyi sola kaydırmış olduk.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 07 Nisan 2017, 16:26:22
@muuzoo  teşekkürler anladım şimdi. Eğer ilk önce düşük biti göndermek istersek aşağıdaki gibi bir kullanım olacaktı sanırım

dout <=tx_buf[0];
tx_buf <= {1'b0, tx_buf[7:1]};
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: superconductor - 07 Nisan 2017, 20:29:53
@Mucit23 hocam, Psoc üzerinde verilogda yazdığınız modül ile mcu arasında nasıl veri alışveriş yapıyorsun? Paralel IO tarzı birşey mi? Benimde ilgimi çekti, hemen bulabileceğim bir kit önerir misin?
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 07 Nisan 2017, 22:33:05
Hocam ilk başta bende bilmiyordum ama öğrendim. Cypress'in forumuna sorarak öğrendim.
http://www.cypress.com/forum/psoc-5-known-problems-and-solutions/verilog-c-bidirectional-data-transfer
http://www.cypress.com/comment/392376#comment-392376

C tarafından Verilog'a göndermeyi daha önce sormuştum. Onu şuanda yapabiliyorum. Bugün Verilog Tarafındaki bilgiyiokuma işlemini sordum. Onuda hemen gösterdiler yalnız henüz deneyemedim.

Aslında bunu yapmanın birkaç yolu var. Eğer Verilog'da hazırladığınız modülde Input ve Output'lara Şema üzerinden Control_Reg Veya Status_Reg gibi hazır donanımlarla ulaşabiliyorsunuz.

Örneğin Devre şemasına Control_Reg donanımı ekleyince C tarafında Proje ağacına Control_Reg'e erişmek için fonksiyonlar otomatikmen oluşturuluyor. Siz bu fonksiyonlara sadece bir veri gönderiyorsunuz. Gönderdiğiniz veri Devre şemasında nere yönlendirdiyseniz oraya gidiyor. Seçenek çok gerçekten. Tasarımı size kalmış.

Yukarıda verdiğim linklerde şema ile hiç uğraşmadan veri nasıl gönderilir veya alınır o konu anlatılıyor. Örnekde var.

Cypress'in forumu çok aktif. Herhalde firmanın ücretli çalışanları sürekli forumu takip ediyorlar. Bazı kullanıcılar mesaj yazdıktan sonra hemen cevap verebiliyorlar. Destekleri oldukça iyi.

Çalışmalarımı şuanda CY8CKIT-050 PSoC® 5LP kartı ile yapıyorum. Kart üzerinde yeterli seviyede çevre donanımı var.  Fakat 99$ fiyatı var. Eğer hızlı başlangıç yapmak istiyorsanız şu kartıda kullanabilirsiniz.
http://www.cypress.com/documentation/development-kitsboards/psoc-4-cy8ckit-049-4xxx-prototyping-kits

Fiyatı sadece 4$!! Bende bu da var yalnız tam anlamıyla uğraşamadım. Bunun kendi üzerinde programlayıcı yok Kart üzerinde PSOC 4100 ve USB seri dönüştürücü var. BoatLoader ile programlamak gerekiyor. Kendi dökümanlarında anlatılıyordu nasıl yapılacağı ben uğraşmadım açıkçası.

Fiyatları pahalı olmasa Şu PSoC 5 serici mükemmel çipler içerisine 80Mhz CortexM3 MCU, FPGA DMA, ADC, DAC, OPAMP, CAPSENSE Çeşitli Haberleşme protokolleri (USB I2C SPI CAN...) vs her türlü var. 

Bu kadar yaygın kullanılmamasının sebebi piyasaya yüksek bir fiyatla girmiş olması sanırım.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 11 Nisan 2017, 16:33:01
Arkadaşlar bir yerde takıldım ufaktan bir fikre ihtiyacım var.

Benim yapmış olduğum verilog modülünde Start girişinden lojik 1 verdiğim zaman girişteki 1 byte veriyi gönderip dursun istiyorum. Daha sonra tekrar 1 byte veri göndermek istersem modülü resetlerim diye düşündüm.

Fakat resetleme işlemini yapamıyorum. Modülde bir reset girişi var. Bu reset girişinden lojik 1 uyguladığım zaman SPI bloğundaki bazı bayrakları sıfırlamam gerekiyor.

Yazdığım kod bu şekilde.
`include "cypress.v"
//`#end` -- edit above this line, do not edit this line
// Generated on 04/11/2017 at 15:17
// Component: ParalelToSerial
module ParalelToSerial (
output  Busy,
output  Clkout,
output  Dout,
input   Clkin,
input  [7:0] Din,
input   Reset,
input   Start
);

//`#start body` -- edit after this line, do not edit this line

    reg dout;
    reg clkout;
    reg reset;
    reg tx_en;
    reg [7:0]tx_buf;
    reg [3:0]cnt_spi;

    initial begin
      reset <= 1'b0;
      clkout <= 1'b0;
      tx_en <= 1'b0;
      cnt_spi <= 1'b0;
    end
   
    always @ (negedge Clkin)
    begin 
       if (Start == 1'b1 && reset == 1'b0)
       begin     
         reset <= 1'b1;
         tx_buf <= Din;
         tx_en <= 1'b1;
       end
       
       if(tx_en == 1'b1)// shift işlemi yap
       begin   
            tx_buf <= {tx_buf[6:0], 1'b0};
            cnt_spi <= cnt_spi + 1;
       end
       
       if(cnt_spi==7)  //aktarım tamamlandı
       begin
         cnt_spi <= 1'b0;
         tx_en <= 1'b0;
       end
    end

    assign Busy = tx_en;
    assign Dout = tx_buf[7];
    assign Clkout = tx_en & Clkin;   
   
//`#end` -- edit above this line, do not edit this line
endmodule


Reset girişini farklı bir always bloğunda sorguluyorum. Reset 1 ise always gerçekleşecek fakat bu işlemi yaptığım zaman  "Can't handle registered multi driver" 

Aynı register'lara birden fazla always bloğu içerisinde erişmeye çalışıca sürekli bu hatayı alıyorum ve elimi kolumu bağlıyor.

Şuanda kodum, Start girişi 1 ise 1 byte veriyi gönderip duruyor fakat tekrar göndermek için reset registerini sıfırlamam gerekiyor onuda yapamadım.

@muuzoo @superconductor  hocam bu işi düzgün bir şekilde nasıl yapabilirim? Yani SPI protokolünü oturtturdum ama kontrol işleri tam olmadı. Bu sorunu çözmem gerekiyor.

Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: muuzoo - 11 Nisan 2017, 18:43:17
@Mucit23 reset işlemini farklı bir always içinde sorgulatmak yerine neden aynı always içinde yapmıyorsun. Ekteki kod verilog için asenkron reset örneği.


always @(posedge clk or posedge reset) begin
    if(reset == 1'b1)
       reg <= 0; //reset condition
    else
       reg <= whatever; // non-reset condition
end


Bu da senkron reset örneği. Hangisi işine yararsa:

always @(posedge clk) begin
   if(reset)
      reg <= 0; //reset condition
   else
      reg <= whatever; //non-reset condition
end
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 12 Nisan 2017, 10:42:04
@muuzoo hocam verilogda yeniyim bu yüzden saçma sapan işlere kalkışmam normaldir.  :) Kod tecrübem yok.

Hocam bu resetleme işlemini yapamadım. Şuanda bahsettiğiniz şekilde yaptım hata vermiyor ama düzgünde çalışmıyor. Yukarıdaki kodda yapmak istediğim şudur aslında

Data girişinden 1 byte veri yükleyip Start girişi 1 yapılırsa o 1 byte veriyi seri olarak gönderip dursun. Tekrar gönderim için Modülü resetleyeyim ve Start girişi tekrar 1 olursa yine girişteki veriyi gönderip dursun. Böyle bir mantık düşünüyorum ama daha iyi çözümlerde olabilir.

Bunu siz olsaydınız nasıl yapardınız? Ben bir Reset flag'ı ile yapmaya çalışıyorum ama herzamanki gibi Mikroişlemciye kod yazar gibi düşünüp verilogda kodlama yapınca paralel işlemlerde hep çuvalladım. :-[ Bazı şeyler hala tam oturmuş değil.  :-\ Bu konuda önerinize ihtiyacım var.

Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 12 Nisan 2017, 13:15:58
Hocam aslında şöyle bir sorun var.

Normalde Reset sinyalinin dışarıdan ne zaman geleceği belli olmuyor. Sizin senkron örneğinizdeki gibi yaparsam şöyle bir sorun oluşuyor.

always @(posedge clk) begin
   if(reset)
      reg <= 0; //reset condition
   else
      reg <= whatever; //non-reset condition
end

Bu komutta if şartının sorgulanabilmesi için Clock sinyalinin periyodu kadar beklemek gerekiyor. Benim Reset sinyalim bir pulse olarak geliyor. pulse genişliği C kodumun işlenme hızı kadar.

Eğer aşağıdaki gibi yaparsamda bir hata alıyorum. Aslında olması gereken budur
always @(posedge clk or posedge reset) begin
    if(reset == 1'b1)
       reg <= 0; //reset condition
    else
       reg <= whatever; // non-reset condition
end

Aldığım hata aşağıdaki gibi.
"A single 'if' statement testing asynchronous conditions is expected"

Bu hatayı çözemedim malesef. Ama biraz daha uğraşsam olacak gibi. Dediğim gibi öğrenerek gidiyorum. Bu yüzden çok hata yapıyorum
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: muuzoo - 12 Nisan 2017, 13:27:45
Yazdığınız kodu gönderebilirseniz daha kolay fikir yürütebiliriz. Ben de verilog' dan fazla anlamam.Okumam var da yazmam pek yok verilog ile  :)  tecrübem daha çok VHDL üzerine ama temelde donanım tasarımı. O yüzden kod üzerinden gitsek daha iyi olur sanki.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 12 Nisan 2017, 13:40:26
hocam şuanda kodum bu şekilde

module ParalelToSerial (
output  Busy,
output  Clkout,
output  Dout,
input   Clkin,
input  [7:0] Din,
input   Reset,
input   Start
);

//`#start body` -- edit after this line, do not edit this line

    reg dout;
    reg clkout;
    reg reset;
    reg tx_en;
    reg [7:0]tx_buf;
    reg [3:0]cnt_spi;

    initial begin
      tx_buf[7] <= 1'b0;
      reset <= 1'b0;
      clkout <= 1'b0;
      tx_en <= 1'b0;
      cnt_spi <= 1'b0;
    end

    always @ (negedge Clkin)
    begin 
          if(Reset == 1'b1)  //Eğer Reset girişi set olursa reset flag'ini sıfırla
          begin
             reset <= 1'b0;
          end

          if (Start == 1'b1 && reset == 1'b0)  //Eğer Reset Flağı sıfır ise ve Start girişi 1 olursa 1 byte gönder ve dur.
          begin     
            reset <= 1'b1;
            tx_buf <= Din;
            tx_en <= 1'b1;
          end
       
          if(tx_en == 1'b1)// shift işlemi yap
          begin   
             tx_buf <= {tx_buf[6:0], 1'b0};
             cnt_spi <= cnt_spi + 1;
          end
       
          if(cnt_spi==7)  //aktarım tamamlandı
          begin
             cnt_spi <= 1'b0;
             tx_en <= 1'b0;
          end
    end

    assign Busy = tx_en;
    assign Dout = tx_buf[7];
    assign Clkout = tx_en & Clkin;   
   
//`#end` -- edit above this line, do not edit this line
endmodule


Hocam nasıl çözeceğiz bu işi. Siz VHDL için anlatın ben verilog'da uygulamaya çalışırım.  :)  Reset girişi ve ve Start girişinin Clock girişinden bağımsız olarak hemen işleme alınması lazım. Diğer türlü Start ve Reset girişlerini always @ (negedge Clkin) bloğunun içerisinde if ile kontrol edersem önreğin reset veya start sinyali verdikten sonra Clock sinyalinin periyodu kadar sonra işleme alınabiliyor.

Dolayısıyla ben C kodunda Start=1 yaptıktan sonra biraz bekleme yapmam gerekiyor.

Hocam özellikle Start girişini senkron bir şekilde yapmam lazım. Bu hepsini çözüyor diyebilirim.


Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: muuzoo - 12 Nisan 2017, 19:27:39
Hata vermesinin sebebi şu. if reset else yapısının else kısmını oluşturmamışsınız. Diğer bütün durumlar reset koşulunun sağlanmadığı durumlarda çalışmalı yani else ya da else if gibi bir yapı ile devam etmelisiniz. Sizin kodunuzda ise sadece if yapıları var. Koşulların sağlanmadığı durumlara dair bir durum yok. Genelde ben bu tarz haberleşme yapıları için FSM yapısı kurmayı tercih eder state tanımlar ve kodu ona göre tasarlarım. Örneğin IDLE, START, TRANSMIT v.b. durumlar oluşturup state aralrında gezinirim.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 12 Nisan 2017, 20:23:51
Hocam o bahsettiğinizi bir kod örneğinde görmüşüm. Switch case yapısına benzer bir yapı ile yapmıştı. Yarın birazda onunla uğraşayım. Bu mantık yanlış olabilir.

Ama anlamadığım nokta şu ki her if yapısına boş bir else yapısı tanımlasam yine aynı hatayı alıyorum.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: muuzoo - 12 Nisan 2017, 22:08:33
Önemli olan reset cond. için yaptığınız tanımalama.

if reset
----- Reset durumunda yapılacaklar
else
---- Diğer tüm işlemler.
end
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 12 Nisan 2017, 22:58:22
Hocam Tamam bunda sıkıntı yok. Peki Start girişini nasıl yapabilirim? Asıl problem o. Start girişi 1 olduğu anda işleme başlaması lazım. Şuanki haliyle bir sonraki Clock darbesini bekliyor.  Normalde Reset durumu dediğiniz gibi olabilir ama Start'ın sıfır olma durumu için Bir senaryom yok. Aslında biraz kafam karıştı ???
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 13 Nisan 2017, 10:56:44
Hocam birde benim psoc üzerindeki verilog derleyicisi always @(*) bloğuna herzaman hata veriyor. Syntax error veriyor. Bu yapı sanırım Psoc üzerindeki verilog'da yok.


PSOC için hazırlamış verilog'a ait bir döküman buldum. Bu dökümandsa always bloğu anlatılmış.


(https://s27.postimg.cc/6iabvzf0j/Ekran_Al_nt_s.jpg)


Hocam Alt tarafta Sesivity list kısmında şunu söylemiş.


Alıntı Yap
The sensitivity list can contain only asynchronous triggers or only synchronous triggers, but not both. For example, the sensitivity list cannot contain always @ (x or posedge clock).
Yani anladığım kadarıyla always bloğuna senkron ve asenkron tetikleme kaynakları aynı anda kullanılamıyor.
İkisini beraber kullanmanın bir yolunu bulmam gerekiyor. Hocam benim şuanda tek sıkıntım Start girişini senkron bir şekilde algılamak.


Bu iş için nasıl bir yöntem önerirsiniz
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 13 Nisan 2017, 11:05:03
Hocam birde şunu sorayım.

İki farklı always bloğunda aynı register üzerinde işlem yapmak istersek hata alıyoruz. Bu VHDL içindemi böyle? Yani bana saçma geliyor. Bir registere birden fazla always bloğunda işlem yapmak istersek nasıl bir yöntem izlenir. Bu işler nasıl yapılır öğrenmek istiyorum.

Hocam hakkınızı helal edin çok soru soruyorum ama dediğim gibi Verilog komple farklı bir dünya.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: muuzoo - 13 Nisan 2017, 14:35:21
Alıntı YapHocam birde şunu sorayım.

İki farklı always bloğunda aynı register üzerinde işlem yapmak istersek hata alıyoruz. Bu VHDL içindemi böyle? Yani bana saçma geliyor. Bir registere birden fazla always bloğunda işlem yapmak istersek nasıl bir yöntem izlenir. Bu işler nasıl yapılır öğrenmek istiyorum.

Hocam hakkınızı helal edin çok soru soruyorum ama dediğim gibi Verilog komple farklı bir dünya.

Tabi ki VHDL'de de öyle. Bunu yazılım mantığı ile düşünmeyin, yazdığınız kodun karşılığında bir devre oluşturuluyor. Kaynak ve hedef mantığında düşünün. PSOC üzerinde muhtemelen bazı kısıtlamalar var. Şu pdf dosyasındaki örnek kod faydalı olacaktır sanıyorum. Hem reset kullanımı hem de enable kullanımı için bir örnek. 14. sayfada

http://www.cypress.com/file/42161/download
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: Mucit23 - 13 Nisan 2017, 16:02:29
Devre mantığını anladım. Üzerinde bayağı düşünmem lazım. Örneği biraz inceleyeyim hocam.
Başlık: Ynt: Verilog'da Basit SPI modülü tasarımı
Gönderen: superconductor - 13 Nisan 2017, 19:06:01
Hocam, always bloklarinin ayni durum ile tetiklendigini dusunun, ornegin clock sinyalinin yukselen kenari. Birinci always icinde register'a 0 yazdiniz, ikinci always icinde ayni register'a farkli bir deger yazdiniz. Bu islemler ayni anda gerceklenecek.. bu durumda register'a ne yazilacak?    Bu durumu şöyle özetleyebiliriz.. iki adet buffer var çıkışları birbirine bağli.. birinin girisine 1 digerine 0 verdik, bu durumda çıkış durumu belirsiz olacaktir.