因為有師弟求助,要在DE2上產生一個1KHz的音頻信號,但是由於我也很久沒碰FPGA,所以昨日在DE2的資料光盤上找到一些e.g.,直接複製下來,拼了一個工程,成功產生1KHz的信號。
硬件就是用FPGA控制WM8731音頻的IC,產生一個1KHz的音頻信號。
語言使用Verilog 描述語言
Besause a junior student ask for help. He want to generate a
1KHz audio signal by DE2 borad. But in fact, I have not used FPGA
for a long time. So I find some example from DE2 CD(1.5 Version)
and put some modules together in a project. It works and gnerate
1KHz audio signal.
下面是全局圖
next is the top block:
一共四個模塊:
4 modules :
AUDIO_DAC.v,I2C_AV_Config.v,Reset_Delay.v,VGA_Audio_PLL.v
下面貼上代碼:
next is the verilog code
module VGA_Audio_PLL (
areset,
inclk0,
c0);
input areset;
input inclk0;
output c0;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
tri0 areset;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif
wire [5:0] sub_wire0;
wire [0:0] sub_wire4 = 1'h0;
wire [0:0] sub_wire1 = sub_wire0[0:0];
wire c0 = sub_wire1;
wire sub_wire2 = inclk0;
wire [1:0] sub_wire3 = {sub_wire4, sub_wire2};
altpll altpll_component (
.areset (areset),
.inclk (sub_wire3),
.clk (sub_wire0),
.activeclock (),
.clkbad (),
.clkena ({6{1'b1}}),
.clkloss (),
.clkswitch (1'b0),
.configupdate (1'b0),
.enable0 (),
.enable1 (),
.extclk (),
.extclkena ({4{1'b1}}),
.fbin (1'b1),
.fbmimicbidir (),
.fbout (),
.fref (),
.icdrclk (),
.locked (),
.pfdena (1'b1),
.phasecounterselect ({4{1'b1}}),
.phasedone (),
.phasestep (1'b1),
.phaseupdown (1'b1),
.pllena (1'b1),
.scanaclr (1'b0),
.scanclk (1'b0),
.scanclkena (1'b1),
.scandata (1'b0),
.scandataout (),
.scandone (),
.scanread (1'b0),
.scanwrite (1'b0),
.sclkout0 (),
.sclkout1 (),
.vcooverrange (),
.vcounderrange ());
defparam
altpll_component.clk0_divide_by = 3,
altpll_component.clk0_duty_cycle = 50,
altpll_component.clk0_multiply_by = 2,
altpll_component.clk0_phase_shift = "0",
altpll_component.compensate_clock = "CLK0",
altpll_component.inclk0_input_frequency = 37037,
altpll_component.intended_device_family = "Cyclone II",
altpll_component.lpm_type = "altpll",
altpll_component.operation_mode = "SOURCE_SYNCHRONOUS",
altpll_component.port_activeclock = "PORT_UNUSED",
altpll_component.port_areset = "PORT_USED",
altpll_component.port_clkbad0 = "PORT_UNUSED",
altpll_component.port_clkbad1 = "PORT_UNUSED",
altpll_component.port_clkloss = "PORT_UNUSED",
altpll_component.port_clkswitch = "PORT_UNUSED",
altpll_component.port_configupdate = "PORT_UNUSED",
altpll_component.port_fbin = "PORT_UNUSED",
altpll_component.port_inclk0 = "PORT_USED",
altpll_component.port_inclk1 = "PORT_UNUSED",
altpll_component.port_locked = "PORT_UNUSED",
altpll_component.port_pfdena = "PORT_UNUSED",
altpll_component.port_phasecounterselect =
"PORT_UNUSED",
altpll_component.port_phasedone = "PORT_UNUSED",
altpll_component.port_phasestep = "PORT_UNUSED",
altpll_component.port_phaseupdown = "PORT_UNUSED",
altpll_component.port_pllena = "PORT_UNUSED",
altpll_component.port_scanaclr = "PORT_UNUSED",
altpll_component.port_scanclk = "PORT_UNUSED",
altpll_component.port_scanclkena = "PORT_UNUSED",
altpll_component.port_scandata = "PORT_UNUSED",
altpll_component.port_scandataout = "PORT_UNUSED",
altpll_component.port_scandone = "PORT_UNUSED",
altpll_component.port_scanread = "PORT_UNUSED",
altpll_component.port_scanwrite = "PORT_UNUSED",
altpll_component.port_clk0 = "PORT_USED",
altpll_component.port_clk1 = "PORT_UNUSED",
altpll_component.port_clk2 = "PORT_UNUSED",
altpll_component.port_clk3 = "PORT_UNUSED",
altpll_component.port_clk4 = "PORT_UNUSED",
altpll_component.port_clk5 = "PORT_UNUSED",
altpll_component.port_clkena0 = "PORT_UNUSED",
altpll_component.port_clkena1 = "PORT_UNUSED",
altpll_component.port_clkena2 = "PORT_UNUSED",
altpll_component.port_clkena3 = "PORT_UNUSED",
altpll_component.port_clkena4 = "PORT_UNUSED",
altpll_component.port_clkena5 = "PORT_UNUSED",
altpll_component.port_extclk0 = "PORT_UNUSED",
altpll_component.port_extclk1 = "PORT_UNUSED",
altpll_component.port_extclk2 = "PORT_UNUSED",
altpll_component.port_extclk3 = "PORT_UNUSED";
endmodule
module Reset_Delay(iCLK,oRESET);
input iCLK;
output reg oRESET;
reg [19:0] Cont;
always@(posedge iCLK)
begin
if(Cont!=20'hFFFFF)
begin
Cont <= Cont+1;
oRESET <= 1'b0;
end
else
oRESET <= 1'b1;
end
endmodule
module I2C_AV_Config ( // Host Side
iCLK,
iRST_N,
// I2C Side
I2C_SCLK,
I2C_SDAT );
// Host Side
input iCLK;
input iRST_N;
// I2C Side
output I2C_SCLK;
inout I2C_SDAT;
// Internal Registers/Wires
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;
// Clock Setting
parameter CLK_Freq = 50000000; // 50 MHz
parameter I2C_Freq = 20000; // 20 KHz
// LUT Data Number
parameter LUT_SIZE = 51;
// Audio Data Index
parameter Dummy_DATA = 0;
parameter SET_LIN_L = 1;
parameter SET_LIN_R = 2;
parameter SET_HEAD_L = 3;
parameter SET_HEAD_R = 4;
parameter A_PATH_CTRL = 5;
parameter D_PATH_CTRL = 6;
parameter POWER_ON = 7;
parameter SET_FORMAT = 8;
parameter SAMPLE_CTRL = 9;
parameter SET_ACTIVE = 10;
// Video Data Index
parameter SET_VIDEO = 11;
///////////////////// I2C Control Clock
////////////////////////
always@(posedge 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_Controller u0 ( .CLOCK(mI2C_CTRL_CLK), // Controller Work
Clock
.I2C_SCLK(I2C_SCLK), // I2C CLOCK
.I2C_SDAT(I2C_SDAT), // I2C DATA
.I2C_DATA(mI2C_DATA), // DATA:[SLAVE_ADDR,SUB_ADDR,DATA]
.GO(mI2C_GO),
// GO transfor
.END(mI2C_END), // END transfor
.ACK(mI2C_ACK), // ACK
.RESET(iRST_N) );
////////////////////////////////////////////////////////////////////
////////////////////// Config Control
////////////////////////////
always@(posedge 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
if(LUT_INDEX<SET_VIDEO)
mI2C_DATA <= {8'h34,LUT_DATA};
else
mI2C_DATA <= {8'h40,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+1;
mSetup_ST <= 0;
end
endcase
end
end
end
////////////////////////////////////////////////////////////////////
///////////////////// Config Data LUT
//////////////////////////
always
begin
case(LUT_INDEX)
// Audio Config Data
Dummy_DATA : LUT_DATA <= 16'h0000;
SET_LIN_L : LUT_DATA <= 16'h001A;
SET_LIN_R : LUT_DATA <= 16'h021A;
SET_HEAD_L : LUT_DATA <= 16'h047B;
SET_HEAD_R : LUT_DATA <= 16'h067B;
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;
// Video Config Data
SET_VIDEO+0 : LUT_DATA <= 16'h1500;
SET_VIDEO+1 : LUT_DATA <= 16'h1741;
SET_VIDEO+2 : LUT_DATA <= 16'h3a16;
SET_VIDEO+3 : LUT_DATA <= 16'h5004;
SET_VIDEO+4 : LUT_DATA <= 16'hc305;
SET_VIDEO+5 : LUT_DATA <= 16'hc480;
SET_VIDEO+6 : LUT_DATA <= 16'h0e80;
SET_VIDEO+7 : LUT_DATA <= 16'h5020;
SET_VIDEO+8 : LUT_DATA <= 16'h5218;
SET_VIDEO+9 : LUT_DATA <= 16'h58ed;
SET_VIDEO+10: LUT_DATA <= 16'h77c5;
SET_VIDEO+11: LUT_DATA <= 16'h7c93;
SET_VIDEO+12: LUT_DATA <= 16'h7d00;
SET_VIDEO+13: LUT_DATA <= 16'hd048;
SET_VIDEO+14: LUT_DATA <= 16'hd5a0;
SET_VIDEO+15: LUT_DATA <= 16'hd7ea;
SET_VIDEO+16: LUT_DATA <= 16'he43e;
SET_VIDEO+17: LUT_DATA <= 16'hea0f;
SET_VIDEO+18: LUT_DATA <= 16'h3112;
SET_VIDEO+19: LUT_DATA <= 16'h3281;
SET_VIDEO+20: LUT_DATA <= 16'h3384;
SET_VIDEO+21: LUT_DATA <= 16'h37A0;
SET_VIDEO+22: LUT_DATA <= 16'he580;
SET_VIDEO+23: LUT_DATA <= 16'he603;
SET_VIDEO+24: LUT_DATA <= 16'he785;
SET_VIDEO+25: LUT_DATA <= 16'h5000;
SET_VIDEO+26: LUT_DATA <= 16'h5100;
SET_VIDEO+27: LUT_DATA <= 16'h0050;
SET_VIDEO+28: LUT_DATA <= 16'h1000;
SET_VIDEO+29: LUT_DATA <= 16'h0402;
SET_VIDEO+30: LUT_DATA <= 16'h0860;
SET_VIDEO+31: LUT_DATA <= 16'h0a18;
SET_VIDEO+32: LUT_DATA <= 16'h1100;
SET_VIDEO+33: LUT_DATA <= 16'h2b00;
SET_VIDEO+34: LUT_DATA <= 16'h2c8c;
SET_VIDEO+35: LUT_DATA <= 16'h2df2;
SET_VIDEO+36: LUT_DATA <= 16'h2eee;
SET_VIDEO+37: LUT_DATA <= 16'h2ff4;
SET_VIDEO+38: LUT_DATA <= 16'h30d2;
SET_VIDEO+39: LUT_DATA <= 16'h0e05;
default: LUT_DATA <= 16'h0000;
endcase
end
////////////////////////////////////////////////////////////////////
endmodule
module AUDIO_DAC ( // Memory Side
oFLASH_ADDR,iFLASH_DATA,
oSDRAM_ADDR,iSDRAM_DATA,
oSRAM_ADDR,iSRAM_DATA,
// Audio Side
oAUD_BCK,
oAUD_DATA,
oAUD_LRCK,
// Control Signals
iSrc_Select,
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; // Dual Channel
parameter SIN_SAMPLE_DATA = 48;
parameter FLASH_DATA_NUM = 1048576; // 1 MWords
parameter SDRAM_DATA_NUM = 4194304; // 4 MWords
parameter SRAM_DATA_NUM = 262144; // 256 KWords
parameter FLASH_ADDR_WIDTH= 20; // 20 Address Line
parameter SDRAM_ADDR_WIDTH= 22; // 22 Address Line
parameter SRAM_ADDR_WIDTH= 18; // 18 Address Line
parameter FLASH_DATA_WIDTH= 8; // 8 Bits
parameter SDRAM_DATA_WIDTH= 16; // 16 Bits
parameter SRAM_DATA_WIDTH= 16; // 16 Bits
//////////// Input Source Number //////////////
parameter SIN_SANPLE = 0;
parameter FLASH_DATA = 1;
parameter SDRAM_DATA = 2;
parameter SRAM_DATA = 3;
//////////////////////////////////////////////////
// Memory Side
output [FLASH_ADDR_WIDTH-1:0] oFLASH_ADDR;
input [FLASH_DATA_WIDTH-1:0] iFLASH_DATA;
output [SDRAM_ADDR_WIDTH:0] oSDRAM_ADDR;
input [SDRAM_DATA_WIDTH-1:0] iSDRAM_DATA;
output [SRAM_ADDR_WIDTH:0] oSRAM_ADDR;
input [SRAM_DATA_WIDTH-1:0] iSRAM_DATA;
// Audio Side
output oAUD_DATA;
output oAUD_LRCK;
output reg oAUD_BCK;
// Control Signals
input [1:0] iSrc_Select;
input iCLK_18_4;
input iRST_N;
// Internal Registers and Wires
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;
//////// DATA Counter ////////
reg [5:0] SIN_Cont;
reg [FLASH_ADDR_WIDTH-1:0] FLASH_Cont;
reg [SDRAM_ADDR_WIDTH-1:0] SDRAM_Cont;
reg [SRAM_ADDR_WIDTH-1:0] SRAM_Cont;
////////////////////////////////////
reg [DATA_WIDTH-1:0] Sin_Out;
reg [DATA_WIDTH-1:0] FLASH_Out;
reg [DATA_WIDTH-1:0] SDRAM_Out;
reg [DATA_WIDTH-1:0] SRAM_Out;
reg [DATA_WIDTH-1:0] FLASH_Out_Tmp;
reg [DATA_WIDTH-1:0] SDRAM_Out_Tmp;
reg [DATA_WIDTH-1:0] SRAM_Out_Tmp;
reg LRCK_1X;
reg LRCK_2X;
reg LRCK_4X;
//////////// AUD_BCK Generator //////////////
always@(posedge 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 Generator //////////////
always@(posedge 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;
//////////////////////////////////////////////////
////////// Sin LUT ADDR Generator //////////////
always@(negedge 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
//////////////////////////////////////////////////
////////// FLASH ADDR Generator //////////////
always@(negedge LRCK_4X or negedge iRST_N)
begin
if(!iRST_N)
FLASH_Cont <= 0;
else
begin
if(FLASH_Cont < FLASH_DATA_NUM-1 )
FLASH_Cont <= FLASH_Cont+1;
else
FLASH_Cont <= 0;
end
end
assign oFLASH_ADDR = FLASH_Cont;
//////////////////////////////////////////////////
////////// FLASH DATA Reorder
//////////////
always@(posedge LRCK_4X or negedge iRST_N)
begin
if(!iRST_N)
FLASH_Out_Tmp <= 0;
else
begin
if(FLASH_Cont[0])
FLASH_Out_Tmp[15:8] <= iFLASH_DATA;
else
FLASH_Out_Tmp[7:0] <= iFLASH_DATA;
end
end
always@(negedge LRCK_2X or negedge iRST_N)
begin
if(!iRST_N)
FLASH_Out <= 0;
else
FLASH_Out <= FLASH_Out_Tmp;
end
//////////////////////////////////////////////////
////////// SDRAM ADDR Generator //////////////
always@(negedge LRCK_2X or negedge iRST_N)
begin
if(!iRST_N)
SDRAM_Cont <= 0;
else
begin
if(SDRAM_Cont < SDRAM_DATA_NUM-1 )
SDRAM_Cont <= SDRAM_Cont+1;
else
SDRAM_Cont <= 0;
end
end
assign oSDRAM_ADDR = SDRAM_Cont;
//////////////////////////////////////////////////
////////// SDRAM DATA Latch
//////////////
always@(posedge LRCK_2X or negedge iRST_N)
begin
if(!iRST_N)
SDRAM_Out_Tmp <= 0;
else
SDRAM_Out_Tmp <= iSDRAM_DATA;
end
always@(negedge LRCK_2X or negedge iRST_N)
begin
if(!iRST_N)
SDRAM_Out <= 0;
else
SDRAM_Out <= SDRAM_Out_Tmp;
end
//////////////////////////////////////////////////
//////////// SRAM ADDR Generator
////////////
always@(negedge LRCK_2X or negedge iRST_N)
begin
if(!iRST_N)
SRAM_Cont <= 0;
else
begin
if(SRAM_Cont < SRAM_DATA_NUM-1 )
SRAM_Cont <= SRAM_Cont+1;
else
SRAM_Cont <= 0;
end
end
assign oSRAM_ADDR = SRAM_Cont;
//////////////////////////////////////////////////
////////// SRAM DATA Latch
//////////////
always@(posedge LRCK_2X or negedge iRST_N)
begin
if(!iRST_N)
SRAM_Out_Tmp <= 0;
else
SRAM_Out_Tmp <= iSRAM_DATA;
end
always@(negedge LRCK_2X or negedge iRST_N)
begin
if(!iRST_N)
SRAM_Out <= 0;
else
SRAM_Out <= SRAM_Out_Tmp;
end
//////////////////////////////////////////////////
////////// 16 Bits PISO MSB First //////////////
always@(negedge oAUD_BCK or negedge iRST_N)
begin
if(!iRST_N)
SEL_Cont <= 0;
else
SEL_Cont <= SEL_Cont+1;
end
assign oAUD_DATA = (iSrc_Select==SIN_SANPLE) ?
Sin_Out[~SEL_Cont] :
(iSrc_Select==FLASH_DATA) ? FLASH_Out[~SEL_Cont]:
(iSrc_Select==SDRAM_DATA) ? SDRAM_Out[~SEL_Cont]:
SRAM_Out[~SEL_Cont] ;
//////////////////////////////////////////////////
//////////// Sin Wave ROM Table //////////////
always@(SIN_Cont)
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