日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python 开发板 i2s_[Craftor原创] I2S总线接口设计(Verilog)

發布時間:2024/8/23 python 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 开发板 i2s_[Craftor原创] I2S总线接口设计(Verilog) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文有Craftor原創,轉載請保留出處。

I2S是數字音頻的接口,這里不用多說,請讀者自己查閱相關資料。

本文中要設計的是FPGA與數字音頻芯片的I2S接口時序。簡單點說,就是通過FPGA向音頻芯片寫數據,通過的是I2S總線,因為這個總線比較麻煩,我在這里做成接口模塊,其它模塊直接拿來用就可以了。

提示,I2S總線的接口信號如下:

1、LRCLK:左右聲道控制,高電平時,SDATA上為左聲道數據,低電平時,SDATA上為右聲道數據。(也有相反的情況,請參考不同的音頻芯片的手冊)

2、BCLK:跟SDATA上數據對應的時鐘,上升沿采數據,也可能在下降沿采數據,請注意對應音頻芯片手冊上的說明。

3、SDATA:串行數據,一個BCLK對應一個。

時序圖如下,WS就是LRCLK,BCLK就是SCK。

一、設計思路,數據流向,如下:

二、分析

左聲道和右聲道的數據,分別設計成兩個FIFO即可。重點在于如何將兩路數據拼裝到一起,再轉換成串行的數據。

三、設計

1、LRCLK和BCLK的產生

提示,如果數字音頻的數據是16位的,那么BCLK就是LRCLK的16倍。即在一個LRCLK中,有32個BCLK,16個左聲道數據,16個右聲道數據。同樣,如果數據是12位的,那么BCLK就是LRCLK的24倍。

verilog代碼如下:

// LRCLK & BCLK Generate

reg [7:0] lrclk_cnt = 0;

reg [2:0] bclk_cnt = 0;

always@(posedge clk) begin

lrclk_cnt <= lrclk_cnt + 1;

if (lrclk_cnt == 127) audio_lrclk <= 1'b1;

if (lrclk_cnt == 255) audio_lrclk <= 1'b0;

end

always@(posedge clk) begin

bclk_cnt <= bclk_cnt + 1;

if (bclk_cnt == 3) audio_bclk <= 1'b1;

if (bclk_cnt == 7) audio_bclk <= 1'b0;

end

說明,如果音頻數據的采樣率是48KHz,那么,一般情況下,clk應該是采樣率的256、384或者512倍。比較常見的是256倍,那么,這里的clk=44.8KHz*256=12.288MHz。

之所以用這種計數器的方式產生LRCLK和BCLK,是為下面的裝入數據做準備的。

2、SDATA數據的載入

// DAC Data Assembling

reg [15:0] lbuf = 16'd0;

reg [15:0] rbuf = 16'd0;

always@(negedge clk) begin

case(lrclk_cnt)

// Left

0: audio_sdata <= lbuf[15];

8: audio_sdata <= lbuf[14];

16: audio_sdata <= lbuf[13];

24: audio_sdata <= lbuf[12];

32: audio_sdata <= lbuf[11];

40: audio_sdata <= lbuf[10];

48: audio_sdata <= lbuf[9];

56: audio_sdata <= lbuf[8];

64: audio_sdata <= lbuf[7];

72: audio_sdata <= lbuf[6];

80: audio_sdata <= lbuf[5];

88: audio_sdata <= lbuf[4];

96: audio_sdata <= lbuf[3];

104: audio_sdata <= lbuf[2];

112: audio_sdata <= lbuf[1];

120: audio_sdata <= lbuf[0];

// Right

128: audio_sdata <= rbuf[15];

136: audio_sdata <= rbuf[14];

144: audio_sdata <= rbuf[13];

152: audio_sdata <= rbuf[12];

160: audio_sdata <= rbuf[11];

168: audio_sdata <= rbuf[10];

176: audio_sdata <= rbuf[9];

184: audio_sdata <= rbuf[8];

192: audio_sdata <= rbuf[7];

200: audio_sdata <= rbuf[6];

208: audio_sdata <= rbuf[5];

216: audio_sdata <= rbuf[4];

224: audio_sdata <= rbuf[3];

232: audio_sdata <= rbuf[2];

240: audio_sdata <= rbuf[1];

248: audio_sdata <= rbuf[0];

endcase

end

說明,至于在計數器的哪個值上將數據賦值,以上的代碼都是經過仿真和實測的,讀者可以自己仿真觀察一下就知道了。

3、FIFO數據的讀取

第2節代碼中可以看到,sdata的數據是從lbuf和rbuf中取的,那么下面的模塊就是如何將數據從FIFO中取出,并放到lbur和rbuf中了。

// Fetch Audio Data From FIFO

assign lfifo_rd_clk = clk;

assign rfifo_rd_clk = clk;

always@(negedge clk) begin

case(lrclk_cnt)

125:

begin

if(!rfifo_empty) rfifo_rd_en <= 1;

end

126:

begin

rfifo_rd_en <= 0;

rbuf <= rfifo_dout;

end

253:

begin

if(!lfifo_empty) lfifo_rd_en <= 1;

end

254:

begin

lfifo_rd_en <= 0;

lbuf <= lfifo_dout;

end

endcase

end

說明,上面取數據對應的計數器值也是經過仿真和實測的,沒有問題,讀者可以自己仿真觀察下。

最后,上面的代碼都是經過作者實測的。

測試情況:

1、找一個mp3或者其它音頻文件,48KHz的采樣率以上,如果采樣率不是48KHz的,通過Adobe Audition(原Cool Edit)軟件調整采樣率(升采樣率會出現雜音,你懂的)。

2、用Matlab打開,可以看到在計算機上的音頻文件的數據是經過歸一化的。將他們轉化成16位的二進制數(unsigned int類型的也一樣),然后另存為二進制文件。

3、通過USB接口(見EZ-USB與FPGA的通信接口設計),自己編寫的軟件,將這個二進制文件發送下去。FPGA端連續不斷的將數據輸出即可聽到聲音。(軟件通過USB發送數據下去的時候,最好將文件切成1K的段發下去,因為FPGA的FIFO緩沖區沒那么大,USB發送數據的延時等待也要設置成200ms以上,不然數據流會斷掉)

文中完整的代碼:

總結

以上是生活随笔為你收集整理的python 开发板 i2s_[Craftor原创] I2S总线接口设计(Verilog)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。