Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CUsersMISHADocumentsМИЭТПрограммируемые логические интегральные схем.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.84 Mб
Скачать

Приложение 4

module audiocodec (input start, input clk, input AUD_DACLRCK, input AUD_BCLK,

output AUD_DACDAT, output I2C_SCLK, inout I2C_SDAT, output [3:0] led);

reg [4:0] ima_index_table [0:7];

reg [14:0] ima_step_table [0:88];

reg start_i2c=1'b0;

reg [8:0] data=9'b0;

reg [6:0] addr=6'b0;

reg [15:0] vol=16'b0;

reg [4:0] state=5'b0000;

reg [1:0] LRC=2'b00;

reg [3:0] i=4'b1111;

reg lg=1'b0;

reg lgg=1'b0;

reg f=1'b0;

reg g=1'b0;

reg [15:0] sample=16'b1000_0000_0000_0000;

reg [15:0] newsample=16'b0;

reg [6:0] step_index=7'b0;

reg [6:0] step_index_prev=7'b0;

reg [1:0] decode_state=2'b00;

wire done;

wire [3:0] wmus;

wire [14:0] step;

wire [4:0] index;

assign step=ima_step_table[step_index];

assign index=ima_index_table[wmus[2:0]];

assign led[3]=lg;

assign led[2]=lgg;

assign AUD_DACDAT=start?sample[i]:1'b0;

initial begin

$readmemb("ima_index_table.txt",ima_index_table);

$readmemh("ima_step_table.txt",ima_step_table);

end

always @(posedge clk)

case (state)

5'b00000: //Power Down Control: enable device, line output, DAC

begin

addr<=7'b0000110;

data<=9'b001100111;

start_i2c<=1'b1;

state<=state+1;

end

5'b00001:

begin

start_i2c<=1'b0;

state<=state+1;

end

5'b00010: //Analogue Audio Path Control: DAC Select=1

if (done)

begin

addr<=7'b0000100;

data<=9'b000010000;

start_i2c<=1'b1;

state<=state+1;

end

5'b00011:

begin

start_i2c<=1'b0;

state<=state+1;

end

5'b00100:

if (done) //Digital Audio Interface Format: Master Mode, DSP Mode A, 16 bits

begin

addr<=7'b0000111;

data<=9'b001010011;

start_i2c<=1'b1;

state<=state+1;

end

5'b00101:

begin

start_i2c<=1'b0;

state<=state+1;

end

5'b00110: //Active Control: ACTIVE=0

if (done)

begin

addr<=7'b0001001;

data<=9'b000000000;

start_i2c<=1'b1;

state<=state+1;

end

5'b00111:

begin

start_i2c<=1'b0;

state<=state+1;

end

5'b01000: //Active Control: ACTIVE=1

if (done)

begin

addr<=7'b0001001;

data<=9'b000000001;

start_i2c<=1'b1;

state<=state+1;

end

5'b01001:

begin

start_i2c<=1'b0;

state<=state+1;

end

5'b01010:

if (done) //Sampling Control: DAC - 8 kHz, use 12 MHz MCLK, USB Mode, MCLK divided by 2

begin

addr<=7'b0001000;

data<=9'b001001101; //9'b001101011; 41 kHz //9'b001001101 8 kHz // 9'b001011001 // 32 kHz

start_i2c<=1'b1;

state<=state+1;

end

5'b01011:

begin

start_i2c<=1'b0;

state<=state+1;

end

5'b01100: //Active Control: ACTIVE=0

if (done)

begin

addr<=7'b0001001;

data<=9'b000000000;

start_i2c<=1'b1;

state<=state+1;

end

5'b01101:

begin

start_i2c<=1'b0;

state<=state+1;

end

5'b01110: //Active Control: ACTIVE=1

if (done)

begin

addr<=7'b0001001;

data<=9'b000000001;

start_i2c<=1'b1;

state<=state+1;

end

5'b01111:

begin

start_i2c<=1'b0;

state<=state+1;

end

5'b10000: // LZCEN=1

if (done)

begin

addr<=7'b0000010;

data<=9'b0011111001;

start_i2c<=1'b1;

state<=state+1;

end

5'b10001:

begin

start_i2c<=1'b0;

state<=state+1;

end

5'b10010: // RZCEN=1

if (done)

begin

addr<=7'b0000011;

data<=9'b0011111001;

start_i2c<=1'b1;

state<=state+1;

end

5'b10011:

begin

start_i2c<=1'b0;

lg<=1'b1;

end

endcase

always @(negedge AUD_BCLK)

if (start)

begin

case (decode_state)

2'b00:

begin

newsample<={{4{1'b0}},step[14:3]}+(wmus[0]?{{3{1'b0}},step[14:2]}:16'b0)+(wmus[1]?{{2{1'b0}},step[14:1]}:16'b0)+(wmus[2]?{{2{1'b0}},step}:16'b0);

decode_state<=decode_state+1;

end

2'b01:

begin

if (wmus[3])

begin

if (newsample>sample)

newsample<=16'b0;

else

newsample<=sample-newsample;

end

else

begin

if (newsample>(16'b1111_1111_1111_1111 - sample))

newsample<=16'b1111_1111_1111_1111;

else

newsample<=sample+newsample;

end

if (index[4])

begin

if (step_index>7'b0)

step_index<=step_index-1;

end

else

begin

if ((step_index+index)>88)

step_index<=88;

else

step_index<=step_index+index;

end

decode_state<=decode_state+1;

end

endcase

if (i>0)

i<=i-1;

if (i==0&!f)

begin

if (g)

begin

vol<=vol+1;

decode_state<=2'b00;

step_index_prev<=step_index;

step_index<=step_index_prev;

sample<=newsample;

end

f<=1'b1;

i<=4'b1111;

end

if (LRC[0]&!LRC[1])

begin

lgg<=1'b1;

decode_state<=2'b00;

i<=4'b1111;

f<=1'b0;

if (vol<59903)

begin

sample<=newsample;

step_index_prev<=step_index;

step_index<=step_index_prev;

g<=1'b1;

if (g)

begin

vol<=vol+1;

end

end

else

begin

step_index_prev<=7'b0;

step_index<=7'b0;

g<=1'b0;

sample<=16'b1000_0000_0000_0000;

vol<=16'b0;

end

end

end

else

begin

step_index_prev<=7'b0;

decode_state<=2'b00;

g<=1'b0;

f<=1'b0;

step_index<=7'b0;

sample<=16'b1000_0000_0000_0000;

i<=4'b1111;

vol<=16'b0;

end

always @(posedge AUD_BCLK)

begin

LRC[0]<=AUD_DACLRCK;

LRC[1]<=LRC[0];

end

i2c toaud (.start(start_i2c),

.clk50(clk),

.data(data),

.addr(addr),

.I2C_SCLK(I2C_SCLK),

.I2C_SDAT(I2C_SDAT),

.done(done),

.led(led[1:0]));

ROM r(.address(vol),

.clock(clk),

.q(wmus));

endmodule