在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 4051|回复: 1

用de2实现音频解码

[复制链接]
发表于 2010-4-27 16:52:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
module audio_test
(
  //////////////////// Clock Input   ////////////////////  
  CLOCK_27,      // 27 MHz
  CLOCK_50,      // 50 MHz
  EXT_CLOCK,      // External Clock
  //////////////////// Push Button  ////////////////////
  KEY,       // Pushbutton[3:0]
  //////////////////// DPDT Switch  ////////////////////
  SW,        // Toggle Switch[17:0]
  //////////////////// 7-SEG Dispaly ////////////////////
  HEX0,       // Seven Segment Digit 0
  HEX1,       // Seven Segment Digit 1
  HEX2,       // Seven Segment Digit 2
  HEX3,       // Seven Segment Digit 3
  HEX4,       // Seven Segment Digit 4
  HEX5,       // Seven Segment Digit 5
  HEX6,       // Seven Segment Digit 6
  HEX7,       // Seven Segment Digit 7
  //////////////////////// LED  ////////////////////////
  LEDG,       // LED Green[8:0]
  LEDR,       // LED Red[17:0]
  //////////////////////// UART ////////////////////////
  UART_TXD,      // UART Transmitter
  UART_RXD,      // UART Receiver
  //////////////////////// IRDA ////////////////////////
// IRDA_TXD,      // IRDA Transmitter
  IRDA_RXD,      // IRDA Receiver
  ///////////////////// SDRAM Interface  ////////////////
  DRAM_DQ,      // SDRAM Data bus 16 Bits
  DRAM_ADDR,      // SDRAM Address bus 12 Bits
  DRAM_LDQM,      // SDRAM Low-byte Data Mask
  DRAM_UDQM,      // SDRAM High-byte Data Mask
  DRAM_WE_N,      // SDRAM Write Enable
  DRAM_CAS_N,      // SDRAM Column Address Strobe
  DRAM_RAS_N,      // SDRAM Row Address Strobe
  DRAM_CS_N,      // SDRAM Chip Select
  DRAM_BA_0,      // SDRAM Bank Address 0
  DRAM_BA_1,      // SDRAM Bank Address 0
  DRAM_CLK,      // SDRAM Clock
  DRAM_CKE,      // SDRAM Clock Enable
  //////////////////// Flash Interface  ////////////////
  FL_DQ,       // FLASH Data bus 8 Bits
  FL_ADDR,      // FLASH Address bus 22 Bits
  FL_WE_N,      // FLASH Write Enable
  FL_RST_N,      // FLASH Reset
  FL_OE_N,      // FLASH Output Enable
  FL_CE_N,      // FLASH Chip Enable
  //////////////////// SRAM Interface  ////////////////
  SRAM_DQ,      // SRAM Data bus 16 Bits
  SRAM_ADDR,      // SRAM Address bus 18 Bits
  SRAM_UB_N,      // SRAM High-byte Data Mask
  SRAM_LB_N,      // SRAM Low-byte Data Mask
  SRAM_WE_N,      // SRAM Write Enable
  SRAM_CE_N,      // SRAM Chip Enable
  SRAM_OE_N,      // SRAM Output Enable
  //////////////////// ISP1362 Interface ////////////////
  OTG_DATA,      // ISP1362 Data bus 16 Bits
  OTG_ADDR,      // ISP1362 Address 2 Bits
  OTG_CS_N,      // ISP1362 Chip Select
  OTG_RD_N,      // ISP1362 Write
  OTG_WR_N,      // ISP1362 Read
  OTG_RST_N,      // ISP1362 Reset
  OTG_FSPEED,      // USB Full Speed, 0 = Enable, Z = Disable
  OTG_LSPEED,      // USB Low Speed,  0 = Enable, Z = Disable
  OTG_INT0,      // ISP1362 Interrupt 0
  OTG_INT1,      // ISP1362 Interrupt 1
  OTG_DREQ0,      // ISP1362 DMA Request 0
  OTG_DREQ1,      // ISP1362 DMA Request 1
  OTG_DACK0_N,     // ISP1362 DMA Acknowledge 0
  OTG_DACK1_N,     // ISP1362 DMA Acknowledge 1
  //////////////////// LCD Module 16X2  ////////////////
  LCD_ON,       // LCD Power ON/OFF
  LCD_BLON,      // LCD Back Light ON/OFF
  LCD_RW,       // LCD Read/Write Select, 0 = Write, 1 = Read
  LCD_EN,       // LCD Enable
  LCD_RS,       // LCD Command/Data Select, 0 = Command, 1 = Data
  LCD_DATA,      // LCD Data bus 8 bits
  //////////////////// SD_Card Interface ////////////////
  SD_DAT,       // SD Card Data
  SD_DAT3,      // SD Card Data 3
  SD_CMD,       // SD Card Command Signal
  SD_CLK,       // SD Card Clock
  //////////////////// USB JTAG link ////////////////////
  TDI,         // CPLD -> FPGA (data in)
  TCK,         // CPLD -> FPGA (clk)
  TCS,         // CPLD -> FPGA (CS)
     TDO,         // FPGA -> CPLD (data out)
  //////////////////// I2C  ////////////////////////////
  I2C_SDAT,      // I2C Data
  I2C_SCLK,      // I2C Clock
  //////////////////// PS2  ////////////////////////////
  PS2_DAT,      // PS2 Data
  PS2_CLK,      // PS2 Clock
  //////////////////// VGA  ////////////////////////////
  VGA_CLK,         // VGA Clock
  VGA_HS,       // VGA H_SYNC
  VGA_VS,       // VGA V_SYNC
  VGA_BLANK,      // VGA BLANK
  VGA_SYNC,      // VGA SYNC
  VGA_R,         // VGA Red[9:0]
  VGA_G,        // VGA Green[9:0]
  VGA_B,        // VGA Blue[9:0]
  //////////// Ethernet Interface ////////////////////////
  ENET_DATA,      // DM9000A DATA bus 16Bits
  ENET_CMD,      // DM9000A Command/Data Select, 0 = Command, 1 = Data
  ENET_CS_N,      // DM9000A Chip Select
  ENET_WR_N,      // DM9000A Write
  ENET_RD_N,      // DM9000A Read
  ENET_RST_N,      // DM9000A Reset
  ENET_INT,      // DM9000A Interrupt
  ENET_CLK,      // DM9000A Clock 25 MHz
  //////////////// Audio CODEC  ////////////////////////
  AUD_ADCLRCK,     // Audio CODEC ADC LR Clock
  AUD_ADCDAT,      // Audio CODEC ADC Data
  AUD_DACLRCK,     // Audio CODEC DAC LR Clock
     AUD_DACDAT,      // Audio CODEC DAC Data
  AUD_BCLK,      // Audio CODEC Bit-Stream Clock
  AUD_XCK,      // Audio CODEC Chip Clock
  //////////////// TV Decoder  ////////////////////////
  TD_DATA,         // TV Decoder Data bus 8 bits
  TD_HS,       // TV Decoder H_SYNC
  TD_VS,       // TV Decoder V_SYNC
  TD_RESET,      // TV Decoder Reset
  //////////////////// GPIO ////////////////////////////
  GPIO_0,       // GPIO Connection 0
  GPIO_1       // GPIO Connection 1
);
//////////////////////// Clock Input   ////////////////////////
input   CLOCK_27;    // 27 MHz
input   CLOCK_50;    // 50 MHz
input   EXT_CLOCK;    // External Clock
//////////////////////// Push Button  ////////////////////////
input [3:0] KEY;     // Pushbutton[3:0]
//////////////////////// DPDT Switch  ////////////////////////
input [17:0] SW;      // Toggle Switch[17:0]
//////////////////////// 7-SEG Dispaly ////////////////////////
output [6:0] HEX0;     // Seven Segment Digit 0
output [6:0] HEX1;     // Seven Segment Digit 1
output [6:0] HEX2;     // Seven Segment Digit 2
output [6:0] HEX3;     // Seven Segment Digit 3
output [6:0] HEX4;     // Seven Segment Digit 4
output [6:0] HEX5;     // Seven Segment Digit 5
output [6:0] HEX6;     // Seven Segment Digit 6
output [6:0] HEX7;     // Seven Segment Digit 7
//////////////////////////// LED  ////////////////////////////
output [8:0] LEDG;     // LED Green[8:0]
output [17:0] LEDR;     // LED Red[17:0]
//////////////////////////// UART ////////////////////////////
output   UART_TXD;    // UART Transmitter
input   UART_RXD;    // UART Receiver
//////////////////////////// IRDA ////////////////////////////
//output   IRDA_TXD;    // IRDA Transmitter
input   IRDA_RXD;    // IRDA Receiver
///////////////////////  SDRAM Interface ////////////////////////
inout [15:0] DRAM_DQ;    // SDRAM Data bus 16 Bits
output [11:0] DRAM_ADDR;    // SDRAM Address bus 12 Bits
output   DRAM_LDQM;    // SDRAM Low-byte Data Mask
output   DRAM_UDQM;    // SDRAM High-byte Data Mask
output   DRAM_WE_N;    // SDRAM Write Enable
output   DRAM_CAS_N;    // SDRAM Column Address Strobe
output   DRAM_RAS_N;    // SDRAM Row Address Strobe
output   DRAM_CS_N;    // SDRAM Chip Select
output   DRAM_BA_0;    // SDRAM Bank Address 0
output   DRAM_BA_1;    // SDRAM Bank Address 0
output   DRAM_CLK;    // SDRAM Clock
output   DRAM_CKE;    // SDRAM Clock Enable
//////////////////////// Flash Interface ////////////////////////
inout [7:0] FL_DQ;     // FLASH Data bus 8 Bits
output [21:0] FL_ADDR;    // FLASH Address bus 22 Bits
output   FL_WE_N;    // FLASH Write Enable
output   FL_RST_N;    // FLASH Reset
output   FL_OE_N;    // FLASH Output Enable
output   FL_CE_N;    // FLASH Chip Enable
//////////////////////// SRAM Interface ////////////////////////
inout [15:0] SRAM_DQ;    // SRAM Data bus 16 Bits
output [17:0] SRAM_ADDR;    // SRAM Address bus 18 Bits
output   SRAM_UB_N;    // SRAM High-byte Data Mask
output   SRAM_LB_N;    // SRAM Low-byte Data Mask
output   SRAM_WE_N;    // SRAM Write Enable
output   SRAM_CE_N;    // SRAM Chip Enable
output   SRAM_OE_N;    // SRAM Output Enable
//////////////////// ISP1362 Interface ////////////////////////
inout [15:0] OTG_DATA;    // ISP1362 Data bus 16 Bits
output [1:0] OTG_ADDR;    // ISP1362 Address 2 Bits
output   OTG_CS_N;    // ISP1362 Chip Select
output   OTG_RD_N;    // ISP1362 Write
output   OTG_WR_N;    // ISP1362 Read
output   OTG_RST_N;    // ISP1362 Reset
output   OTG_FSPEED;    // USB Full Speed, 0 = Enable, Z = Disable
output   OTG_LSPEED;    // USB Low Speed,  0 = Enable, Z = Disable
input   OTG_INT0;    // ISP1362 Interrupt 0
input   OTG_INT1;    // ISP1362 Interrupt 1
input   OTG_DREQ0;    // ISP1362 DMA Request 0
input   OTG_DREQ1;    // ISP1362 DMA Request 1
output   OTG_DACK0_N;   // ISP1362 DMA Acknowledge 0
output   OTG_DACK1_N;   // ISP1362 DMA Acknowledge 1
//////////////////// LCD Module 16X2 ////////////////////////////
inout [7:0] LCD_DATA;    // LCD Data bus 8 bits
output   LCD_ON;     // LCD Power ON/OFF
output   LCD_BLON;    // LCD Back Light ON/OFF
output   LCD_RW;     // LCD Read/Write Select, 0 = Write, 1 = Read
output   LCD_EN;     // LCD Enable
output   LCD_RS;     // LCD Command/Data Select, 0 = Command, 1 = Data
//////////////////// SD Card Interface ////////////////////////
inout   SD_DAT;     // SD Card Data
inout   SD_DAT3;    // SD Card Data 3
inout   SD_CMD;     // SD Card Command Signal
output   SD_CLK;     // SD Card Clock
//////////////////////// I2C  ////////////////////////////////
inout   I2C_SDAT;    // I2C Data
output   I2C_SCLK;    // I2C Clock
//////////////////////// PS2  ////////////////////////////////
input    PS2_DAT;    // PS2 Data
input   PS2_CLK;    // PS2 Clock
//////////////////// USB JTAG link ////////////////////////////
input     TDI;     // CPLD -> FPGA (data in)
input     TCK;     // CPLD -> FPGA (clk)
input     TCS;     // CPLD -> FPGA (CS)
output    TDO;     // FPGA -> CPLD (data out)
//////////////////////// VGA   ////////////////////////////
output   VGA_CLK;       // VGA Clock
output   VGA_HS;     // VGA H_SYNC
output   VGA_VS;     // VGA V_SYNC
output   VGA_BLANK;    // VGA BLANK
output   VGA_SYNC;    // VGA SYNC
output [9:0] VGA_R;       // VGA Red[9:0]
output [9:0] VGA_G;      // VGA Green[9:0]
output [9:0] VGA_B;       // VGA Blue[9:0]
//////////////// Ethernet Interface ////////////////////////////
inout [15:0] ENET_DATA;    // DM9000A DATA bus 16Bits
output   ENET_CMD;    // DM9000A Command/Data Select, 0 = Command, 1 = Data
output   ENET_CS_N;    // DM9000A Chip Select
output   ENET_WR_N;    // DM9000A Write
output   ENET_RD_N;    // DM9000A Read
output   ENET_RST_N;    // DM9000A Reset
input   ENET_INT;    // DM9000A Interrupt
output   ENET_CLK;    // DM9000A Clock 25 MHz
//////////////////// Audio CODEC  ////////////////////////////
output/*inout*/ AUD_ADCLRCK;   // Audio CODEC ADC LR Clock
input   AUD_ADCDAT;    // Audio CODEC ADC Data
inout   AUD_DACLRCK;   // Audio CODEC DAC LR Clock
output   AUD_DACDAT;    // Audio CODEC DAC Data
inout   AUD_BCLK;    // Audio CODEC Bit-Stream Clock
output   AUD_XCK;    // Audio CODEC Chip Clock
//////////////////// TV Devoder  ////////////////////////////
input [7:0] TD_DATA;       // TV Decoder Data bus 8 bits
input   TD_HS;     // TV Decoder H_SYNC
input   TD_VS;     // TV Decoder V_SYNC
output   TD_RESET;    // TV Decoder Reset
//////////////////////// GPIO ////////////////////////////////
inout [35:0] GPIO_0;     // GPIO Connection 0
inout [35:0] GPIO_1;     // GPIO Connection 1
// LCD ON
assign LCD_ON  = 1'b1;
assign LCD_BLON = 1'b1;
// All inout port turn to tri-state
assign DRAM_DQ  = 16'hzzzz;
assign FL_DQ  = 8'hzz;
assign SRAM_DQ  = 16'hzzzz;
assign OTG_DATA = 16'hzzzz;
assign SD_DAT  = 1'bz;
assign ENET_DATA = 16'hzzzz;
assign GPIO_0  = 36'hzzzzzzzzz;
assign GPIO_1  = 36'hzzzzzzzzz;
wire [31:0] mSEG7_DIG;
reg  [31:0] Cont;
wire  VGA_CTRL_CLK;
wire  AUD_CTRL_CLK;
wire [9:0] mVGA_R;
wire [9:0] mVGA_G;
wire [9:0] mVGA_B;
wire [19:0] mVGA_ADDR;
wire  DLY_RST;
assign TD_RESET = 1'b1; // Bypress 27 MHz
assign AUD_ADCLRCK = AUD_DACLRCK;
assign AUD_XCK  = AUD_CTRL_CLK;
assign mSEG7_DIG = { Cont[27:24],Cont[27:24],Cont[27:24],Cont[27:24],
       Cont[27:24],Cont[27:24],Cont[27:24],Cont[27:24] };
assign LEDR  = { Cont[25:23],Cont[25:23],Cont[25:23],
       Cont[25:23],Cont[25:23],Cont[25:23] };
assign LEDG  = { Cont[25:23],Cont[25:23],Cont[25:23] };
  
Reset_Delay r0 (.iCLK(CLOCK_50),.oRESET(DLY_RST) );
Audio_PLL p1(.inclk0(CLOCK_27),.c0(AUD_CTRL_CLK));
I2C_Audio_Config u3(.iCLK(CLOCK_50),
   .iRST_N(DLY_RST),
   .I2C_SCLK(I2C_SCLK),
   .I2C_SDAT(I2C_SDAT) );
  AUDIO_DA u4(.oAUD_BCK(AUD_BCLK),
   .oAUD_DATA(AUD_DACDAT),
   .oAUD_LRCK(AUD_DACLRCK),
   .iCLK_18_4(AUD_CTRL_CLK),
   .iRST_N(KEY[0]) );
endmodule
module AUDIO_DA(
     //数据音频输出引脚
oAUD_BCK,
oAUD_DATA,
oAUD_LRCK,
//控制信号
iCLK_18_4,
iRST_N );
//音频信号参数
parameter REF_CLK     =18432000; //18.432?MHz
parameter SAMPLE_RATE=48000; //48?kHz
parameter DATA_WIDTH  =16;  //16?Bits
parameter CHANNEL_NUM =2; //双通道
parameter SIN_SAMPLE_DATA=48;
//正弦波每个周期的采样点数
output   oAUD_DATA;
output   oAUD_LRCK;
output reg  oAUD_BCK;
input    iCLK_18_4;
input    iRST_N;
reg  [3:0]  BCK_DIV;
reg  [8:0]  LRCK_1X_DIV;
reg  [7:0]  LRCK_2X_DIV;
reg  [6:0]  LRCK_4X_DIV;
reg  [3:0]  SEL_Cont;
reg  [5:0]  SIN_Cont; //数据计数器值,表明当前数据是正弦波每个周期的第几个点
reg [DATA_WIDTH-1:0] Sin_Out;      //正弦波输出数据
reg      LRCK_1X;
reg      LRCK_2X;
reg      LRCK_4X;
////////////?生成AUD_BCK信号//////////////
[email=always@(posedge]always@(posedge[/email] iCLK_18_4 or negedge iRST_N)
begin
if(!iRST_N)
begin
   BCK_DIV <= 0;
   oAUD_BCK <= 0;
end
else
begin
  if(BCK_DIV >= REF_CLK/(SAMPLE_RATE*DATA_WIDTH*CHANNEL_NUM*2)-1 )                           
   begin
    BCK_DIV <= 0;
   oAUD_BCK  <= ~oAUD_BCK;
  end
  else
  BCK_DIV   <= BCK_DIV+1;
       end
         end
////////////生成AUD_LRCK信号//////////////
[email=always@(posedge]always@(posedge[/email] iCLK_18_4 or negedge iRST_N)
begin
if(!iRST_N)
begin
  LRCK_1X_DIV <= 0;
  LRCK_2X_DIV <= 0;
  LRCK_4X_DIV <= 0;
  LRCK_1X  <= 0;
  LRCK_2X  <= 0;
  LRCK_4X  <= 0;
end
else
begin
  //LRCK 1X
  if(LRCK_1X_DIV >= REF_CLK/(SAMPLE_RATE*2)-1)
  begin
   LRCK_1X_DIV <= 0;
   LRCK_1X  <= ~LRCK_1X;
  end
  else
   LRCK_1X_DIV<= LRCK_1X_DIV+1;
   //LRCK 2X
   if(LRCK_2X_DIV >= REF_CLK/ (SAMPLE_RATE*4)-1)
   begin
    LRCK_2X_DIV<= 0;
   LRCK_2X               <= ~LRCK_2X;
  end
else
  LRCK_2X_DIV <= LRCK_2X_DIV+1;  
  //LRCK 4X
  if(LRCK_4X_DIV  >= REF_CLK/ (SAMPLE_RATE*8)-1 )
   begin
    LRCK_4X_DIV<= 0;
    LRCK_4X <= ~LRCK_4X;
   end
   else
   LRCK_4X_DIV <=LRCK_4X_DIV+1;  
  end
end
assign oAUD_LRCK = LRCK_1X;
//////////生成正弦查找表地址//////////////
[email=always@(negedge]always@(negedge[/email] LRCK_1X or negedge iRST_N)
begin
  if(!iRST_N)
SIN_Cont <= 0;
else
begin
  if(SIN_Cont < SIN_SAMPLE_DATA-1 )
  SIN_Cont  <= SIN_Cont+1;
  else
  SIN_Cont  <= 0;
end
end
//////////输出数据//////////////
[email=always@(negedge]always@(negedge[/email] oAUD_BCK or negedge iRST_N)
begin
if(!iRST_N)
SEL_Cont  <= 0;
else
SEL_Cont  <= SEL_Cont+1;
end
assign oAUD_DATA =Sin_Out[~SEL_Cont];  
////////////正弦表//////////////
[email=always@(SIN_Cont]always@(SIN_Cont[/email])
begin
    case(SIN_Cont)
    0  :  Sin_Out       <=      0       ;
    1  :  Sin_Out       <=      4276    ;
    2  :  Sin_Out       <=      8480    ;
    3  :  Sin_Out       <=      12539   ;
    4  :  Sin_Out       <=      16383   ;
    5  :  Sin_Out       <=      19947   ;
    6  :  Sin_Out       <=      23169   ;
    7  :  Sin_Out       <=      25995   ;
    8  :  Sin_Out       <=      28377   ;
    9  :  Sin_Out       <=      30272   ;
    10  :  Sin_Out      <=      31650   ;
11  :  Sin_Out      <=      32486   ;
    12  :  Sin_Out      <=      32767   ;
    13  :  Sin_Out      <=      32486   ;
    14  :  Sin_Out      <=      31650   ;
    15  :  Sin_Out      <=      30272   ;
    16  :  Sin_Out      <=      28377   ;
    17  :  Sin_Out      <=      25995   ;
    18  :  Sin_Out      <=      23169   ;
    19  :  Sin_Out      <=      19947   ;
    20  :  Sin_Out      <=      16383   ;
    21  :  Sin_Out      <=      12539   ;
    22  :  Sin_Out      <=      8480    ;
    23  :  Sin_Out      <=      4276    ;
    24  :  Sin_Out      <=      0       ;
    25  :  Sin_Out      <=      61259   ;
    26  :  Sin_Out      <=      57056   ;
    27  :  Sin_Out      <=      52997   ;
    28  :  Sin_Out      <=      49153   ;
    29  :  Sin_Out      <=      45589   ;
    30  :  Sin_Out      <=      42366   ;
    31  :  Sin_Out      <=      39540   ;
    32  :  Sin_Out      <=      37159   ;
    33  :  Sin_Out      <=      35263   ;
    34  :  Sin_Out      <=      33885   ;
    35  :  Sin_Out      <=      33049   ;
    36  :  Sin_Out      <=      32768   ;
    37  :  Sin_Out      <=      33049   ;
    38  :  Sin_Out      <=      33885   ;
    39  :  Sin_Out      <=      35263   ;
    40  :  Sin_Out      <=      37159   ;
    41  :  Sin_Out      <=      39540   ;
    42  :  Sin_Out      <=      42366   ;
    43  :  Sin_Out      <=      45589   ;
    44  :  Sin_Out      <=      49152   ;
    45  :  Sin_Out      <=      52997   ;
    46  :  Sin_Out      <=      57056   ;
    47  :  Sin_Out      <=      61259   ;
  default :
      Sin_Out <= 0;
endcase
end
endmodule
module I2C_Audio_Config (
  iCLK,     //时钟输入
iRST_N,    //复位信号
I2C_SCLK,    //I2C总线时钟信号输出
I2C_SDAT,

  );   //I2C总线数据信号
input  iCLK;
input  iRST_N;
output I2C_SCLK;
inout  I2C_SDAT;
// 内部寄存器及连线
reg [15:0] mI2C_CLK_DIV;
reg [23:0] mI2C_DATA;
reg   mI2C_CTRL_CLK;
reg   mI2C_GO;
wire  mI2C_END;
wire  mI2C_ACK;
reg [15:0] LUT_DATA;
reg [5:0] LUT_INDEX;
reg [3:0] mSetup_ST;
//时钟参数
parameter  CLK_Freq  = 50000000; //输入的系统时钟50?MHz
parameter  I2C_Freq   = 20000;  //I2C总线时钟20?kHz
//存储音频编/解码器配置数据的查找表容量
parameter  LUT_SIZE  = 10;
//音频编/解码器配置数据索引
parameter  SET_LIN_L  = 0;
parameter  SET_LIN_R  = 1;
parameter  SET_HEAD_L = 2;
parameter  SET_HEAD_R = 3;
parameter  A_PATH_CTRL = 4;
parameter  D_PATH_CTRL = 5;
parameter  POWER_ON  = 6;
parameter  SET_FORMAT = 7;
parameter  SAMPLE_CTRL = 8;
parameter  SET_ACTIVE  = 9;
//////50?MHz时钟分频得到20?kHz的I2C控制时钟//////
[email=always@(posedge]always@(posedge[/email] iCLK or negedge iRST_N)
begin
if(!iRST_N)
begin
  mI2C_CTRL_CLK  <= 0;
  mI2C_CLK_DIV  <= 0;
end
else
begin
  if( mI2C_CLK_DIV < (CLK_Freq/I2C_Freq) )
  mI2C_CLK_DIV <= mI2C_CLK_DIV+1;
  else
  begin
  mI2C_CLK_DIV <= 0;
  mI2C_CTRL_CLK <= ~mI2C_CTRL_CLK;
  end
end
end
////例化I2C控制器///
I2C_Controller u0(
.CLOCK(mI2C_CTRL_CLK), //I2C控制器工作时钟
.I2C_SCLK(I2C_SCLK),  //I2C总线时钟信号
    .I2C_SDAT(I2C_SDAT), //I2C总线数据信号
   .I2C_DATA(mI2C_DATA),  //DATA:[SLAVE_ADDR,SUB_ADDR,DATA]
   .GO(mI2C_GO),       //启动传输
   .END(mI2C_END),  //传输结束标志
   .ACK(mI2C_ACK),    //ACK
   .RESET(iRST_N) );
//////////////////////?配置过程控制?////////////////////////////
[email=always@(posedge]always@(posedge[/email] mI2C_CTRL_CLK or negedge iRST_N)
begin
if(!iRST_N)   //复位
begin
  LUT_INDEX <= 0;
  mSetup_ST <= 0;
  mI2C_GO <= 0;
end
else
begin
  if(LUT_INDEX<LUT_SIZE)
  begin
   case(mSetup_ST)  
   0:begin //第一步:准备数据,启动传输
   mI2C_DATA <= {8'h34,LUT_DATA};
   mI2C_GO <= 1;
   mSetup_ST <= 1;
   end
1: begin
  if(mI2C_END)//第二步:检验传输是否正常结束
    begin
     if(!mI2C_ACK)
     mSetup_ST <= 2;
     else
     mSetup_ST <= 0;      
     mI2C_GO <= 0;
    end
  end
2:begin
//传输结束,改变LUT_INDEX的值,准备传输下一个数据
   LUT_INDEX  <= LUT_INDEX+1;
    mSetup_ST  <= 0;
   end
  endcase
          end
      end
end
/////////////////////?配置数据查找表?//////////////////////////
always
begin
case(LUT_INDEX)
SET_LIN_L  :   LUT_DATA <= 16'h001A;   
SET_LIN_R  :   LUT_DATA <= 16'h021A;  
SET_HEAD_L :   LUT_DATA <= 16'h000B;  
SET_HEAD_R :   LUT_DATA <= 16'h000B;  
A_PATH_CTRL :   LUT_DATA <= 16'h08F8;  
D_PATH_CTRL :   LUT_DATA <= 16'h0A06;
POWER_ON  :   LUT_DATA <= 16'h0C00;
SET_FORMAT :   LUT_DATA <= 16'h0E01;
SAMPLE_CTRL :   LUT_DATA <= 16'h1002;
SET_ACTIVE  :   LUT_DATA <= 16'h1201;
endcase
end
endmodule
module I2C_Controller (
  CLOCK,    //I2C控制器时钟输入
  I2C_SCLK,   //I2C总线时钟信号输出
      I2C_SDAT,    //I2C总线数据信号
  I2C_DATA,   //要传输的数据DATA:[SLAVE_ADDR,SUB_ADDR,DATA]
  GO,         //启动传输
  END,       //传输结束标志
  ACK,        //ACK信号输出
  RESET,      //I2C控制器复位信号
  //以下信号为测试信号
  SD_COUNTER,    //I2C数据发送计数器
  W_R,
  SDO    //I2C控制器发送的串行数据
  );
    input CLOCK;
input [23:0]I2C_DATA;
input GO;
input RESET;
input W_R;
  inout I2C_SDAT;
output I2C_SCLK;
output END;
output ACK;
output [5:0] SD_COUNTER;  //I2C数据发送计数器
output SDO;                  //I2C控制器发送的串行数据
    reg SDO;
   reg SCLK;
reg END;
reg [23:0]SD;
reg [5:0]SD_COUNTER;
wire I2C_SCLK=SCLK | ( ((SD_COUNTER >= 4) & (SD_COUNTER <=30))? ~CLOCK :0 );
wire I2C_SDAT=SDO?1'bz:0 ;    //如果输出数据为1,I2C_SDAT设为高阻
reg ACK1,ACK2,ACK3;
wire ACK=ACK1 | ACK2 |ACK3;    //ACK信号
//--I2CA计数器
always @(negedge RESET or  posedge CLOCK )
begin
  if (!RESET)SD_COUNTER=6'b111111;
    else begin
     if(GO==0)
         SD_COUNTER=0;
       else     
         if(SD_COUNTER<6'b111111)SD_COUNTER=SD_COUNTER+1;
       end
end
always @(negedge RESET or  posedge CLOCK )
begin
  if (!RESET) begin SCLK=1;SDO=1; ACK1=0;ACK2=0;ACK3=0; END=1; end
  else
    case (SD_COUNTER)
6'd0  : begin ACK1=0 ;ACK2=0 ;ACK3=0 ; END=0; SDO=1; SCLK=1;end
//I2C START
6'd1  : begin SD=I2C_DATA;SDO=0;end
6'd2  : SCLK=0;
    //发送从设备地址
6'd3  : SDO=SD[23];
6'd4  : SDO=SD[22];
6'd5  : SDO=SD[21];
6'd6  : SDO=SD[20];
6'd7  : SDO=SD[19];
6'd8  : SDO=SD[18];
6'd9  : SDO=SD[17];
6'd10 : SDO=SD[16];
6'd11 : SDO=1'b1;    //ACK
    //发送从设备寄存器地址
6'd12  : begin SDO=SD[15]; ACK1=I2C_SDAT; end
6'd13  : SDO=SD[14];
6'd14  : SDO=SD[13];
6'd15  : SDO=SD[12];
6'd16  : SDO=SD[11];
6'd17  : SDO=SD[10];
6'd18  : SDO=SD[9];
6'd19  : SDO=SD[8];
6'd20  : SDO=1'b1;   //ACK
    //发送数据
6'd21  : begin SDO=SD[7]; ACK2=I2C_SDAT; end
6'd22  : SDO=SD[6];
6'd23  : SDO=SD[5];
6'd24  : SDO=SD[4];
6'd25  : SDO=SD[3];
6'd26  : SDO=SD[2];
6'd27  : SDO=SD[1];
6'd28  : SDO=SD[0];
6'd29  : SDO=1'b1;  //ACK
//I2C STOP
   6'd30 : begin SDO=1'b0;SCLK=1'b0; ACK3=I2C_SDAT; end
    6'd31 : SCLK=1'b1;
    6'd32 : begin SDO=1'b1; END=1; end
endcase
end
endmodule
module Reset_Delay(iCLK, oRESET);
input  iCLK;
output reg oRESET;
reg [15:0] Cont;
[email=always@(posedge]always@(posedge[/email] iCLK)
begin
  if(Cont!=16'hFFFF)
begin
  Cont  <= Cont+1;
  oRESET <= 1'b0;
end
else
oRESET  <= 1'b1;
end
endmodule


//利用以上的程序可实现de2上简单的音频解码
发表于 2017-9-13 14:17:08 | 显示全部楼层
回复 1# h_zx


   thank you for sharing
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2025-7-14 01:25 , Processed in 0.027198 second(s), 11 queries , Gzip On, MemCached On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表