Estoy intentando obtener una salida de audio de la placa Atlys (usa el códec de audio LM4550). Obtuve el archivo core ac97_controller.v que genera la o / p serial para el códec. Toma las ranuras como entradas y las coloca en las tramas y las transmite al códec, al mismo tiempo que toma la entrada en serie del códec, extrae las ranuras y proporciona las de salida. Solo quiero enviar una onda cuadrada y escribí el módulo superior para eso. Envía las muestras PCM de audio de onda cuadrada (complemento a 2 y 18 bit). También escribí lógica para desactivar el sonido de los auriculares y amp; line_out o / p. Incluso la simulación posterior a la ruta se ve perfecta. Pero cuando lo descargo en el tablero de Atlys, no funciona. ¿Alguien puede decir cuál podría ser el problema? Gracias de antemano.
P.S. Revisé el códec de audio con el proyecto de demostración para AC97 de www.digilentinc.com y funciona, el archivo ac97_controller está allí.
mi código:
module ac97_top(
input sys_clock,
input bit_clock,
output sync,
input sdata_in,
output sdata_out,
output reset
);
reg sys_reset;
reg [7:0] reset_count;
reg [11:0] frame_count;
wire done;
reg [1:0] signal;
reg [15:0] slot0_to_ctrl;
reg [19:0] slot1_to_ctrl;
reg [19:0] slot2_to_ctrl;
reg [19:0] slot3_to_ctrl;
reg [19:0] slot4_to_ctrl;
reg [19:0] slot5_to_ctrl;
reg [19:0] slot6_to_ctrl;
reg [19:0] slot7_to_ctrl;
reg [19:0] slot8_to_ctrl;
reg [19:0] slot9_to_ctrl;
reg [19:0] slot10_to_ctrl;
reg [19:0] slot11_to_ctrl;
reg [19:0] slot12_to_ctrl;
initial
begin
slot0_to_ctrl = 20'h0;
slot1_to_ctrl = 20'h0;
slot2_to_ctrl = 20'h0;
slot3_to_ctrl = 20'h0;
slot4_to_ctrl = 20'h0;
slot5_to_ctrl = 20'h0;
slot6_to_ctrl = 20'h0;
slot7_to_ctrl = 20'h0;
slot8_to_ctrl = 20'h0;
slot9_to_ctrl = 20'h0;
slot10_to_ctrl = 20'h0;
slot11_to_ctrl = 20'h0;
slot12_to_ctrl = 20'h0;
end
ac97_controller A1(
.SYSCLK(sys_clock), // up to 125MHz
.SYSTEM_RESET(sys_reset), // active on 1
.BIT_CLK(bit_clock), // 12,288 MHz
//.SDATA_IN(sdata_in),
.SYNC(sync),
.SDATA_OUT(sdata_out),
.RESET(reset),
.DONE(done),
.Slot0_in(slot0_to_ctrl),
.Slot1_in(slot1_to_ctrl),
.Slot2_in(slot2_to_ctrl),
.Slot3_in(slot3_to_ctrl),
.Slot4_in(slot4_to_ctrl),
.Slot5_in(slot5_to_ctrl),
.Slot6_in(slot6_to_ctrl),
.Slot7_in(slot7_to_ctrl),
.Slot8_in(slot8_to_ctrl),
.Slot9_in(slot9_to_ctrl),
.Slot10_in(slot10_to_ctrl),
.Slot11_in(slot11_to_ctrl),
.Slot12_in(slot12_to_ctrl)
);
initial
begin
sys_reset = 1;
reset_count = 0;
end
always@(posedge sys_clock)
if (reset_count == 255)
sys_reset <= 0;
else reset_count <= reset_count + 1;
always@(posedge bit_clock)
begin
case(frame_count[11:8])
4'd0: begin
slot0_to_ctrl = 16'hF800; // slots 0,1,2,3,4 valid
slot1_to_ctrl = 20'h02_000; // MSB 0 to write the register for master volume(reg 02)
slot2_to_ctrl = 20'h00_000; // unmute line_out
slot3_to_ctrl = {18'h1ffff,2'b00};
slot4_to_ctrl = {18'h1ffff,2'b00};
end
4'd1: begin
slot0_to_ctrl = 16'hF800; // slots 0,1,2,3,4 valid
slot1_to_ctrl = 20'h04_000; // MSB 0 to write the register for headphones(reg 04)
slot2_to_ctrl = 20'h00_000; // unmute headphones
slot3_to_ctrl = {18'h1ffff,2'b00};
slot4_to_ctrl = {18'h1ffff,2'b00};
end
4'd2: begin
slot0_to_ctrl = 16'hF800; // slots 0,1,2,3,4 valid
slot1_to_ctrl = 20'h06_000; // MSB 0 to write the register for headphones(reg 04)
slot2_to_ctrl = 20'h00_000; // unmute mono
slot3_to_ctrl = {18'h1ffff,2'b00};
slot4_to_ctrl = {18'h1ffff,2'b00};
end
4'd3,4'd4,4'd5,4'd6,4'd7:
begin
slot0_to_ctrl = 16'h9800; // slots 0,3,4 valid
slot1_to_ctrl = 20'h00_000; // not considered in codec
slot2_to_ctrl = 20'h00_000; // not considered in codec
slot3_to_ctrl = {18'h1ffff,2'b00};
slot4_to_ctrl = {18'h1ffff,2'b00};
end
default: begin
slot0_to_ctrl = 16'h9800; // slots 0,3,4 valid
slot1_to_ctrl = 20'h00_000; // not considered in codec
slot2_to_ctrl = 20'h00_000; // not considered in codec
slot3_to_ctrl = {18'h20001,2'b00};
slot4_to_ctrl = {18'h20001,2'b00};
end
endcase
end
always@(posedge bit_clock or posedge sys_reset)
if(sys_reset)
frame_count <= 0;
else
frame_count <= frame_count + 1;
//assign led = frame_count[24];
/*always@(posedge sys_clock)
if(sys_reset)
signal <= 0;
else if(signal == 2)
signal <= signal;
else if(done)
signal <= signal + 1;
initial signal = 0;*/
endmodule
ip del controlador:
module ac97_controller(
input SYSCLK, // up to 125MHz
input SYSTEM_RESET, // active on 1
input BIT_CLK, // 12,288 MHz
input SDATA_IN,
output SYNC,
output SDATA_OUT,
output RESET,
output DONE,
input [15:0] Slot0_in,
input [19:0] Slot1_in,
input [19:0] Slot2_in,
input [19:0] Slot3_in,
input [19:0] Slot4_in,
input [19:0] Slot5_in,
input [19:0] Slot6_in,
input [19:0] Slot7_in,
input [19:0] Slot8_in,
input [19:0] Slot9_in,
input [19:0] Slot10_in,
input [19:0] Slot11_in,
input [19:0] Slot12_in
/* output reg [15:0] Slot0_out,
output reg [19:0] Slot1_out,
output reg [19:0] Slot2_out,
output reg [19:0] Slot3_out,
output reg [19:0] Slot4_out,
output reg [19:0] Slot5_out,
output reg [19:0] Slot6_out,
output reg [19:0] Slot7_out,
output reg [19:0] Slot8_out,
output reg [19:0] Slot9_out,
output reg [19:0] Slot10_out,
output reg [19:0] Slot11_out,
output reg [19:0] Slot12_out*/
);
//parameter START_DELAY = 17'd131000;
parameter START_DELAY = 17'd300;
parameter WAIT_FOR_BITCLK_DELAY = 2'b11;
// the states of the state machine
parameter Idle = 2'b00,
Load = 2'b01, // SlotS_out are loaded from Data_reg_in and Data_reg_out is loaded with SlotS_in
Send = 2'b10, // Registers are shifted
Wait_until_Start = 2'b11; // Lines 67-70 & 130
reg [9:0] Increment = 0; // integer Incremented is used for the bit count of a 256-bit frame, as well as SYNC's frequency
reg [16:0] Var_start = 0; // incremented varialbe used to set the signal RESET at the start
reg Reset_Ready;
reg [1:0] Wait_for_BITCLK = 0;
reg [2:0] Frame_Done_reg = 0;
reg [255:0] Data_reg_out = 0;
//reg [255:0] Data_reg_in = 0;
reg [1:0] StC = Idle;
reg [1:0] StN = Idle;
// If SYSTEM_RESET is 1, Var_start (used to count until RESET is deasserted to 1) is reset to 0
always @ (posedge SYSCLK)
if (SYSTEM_RESET)
Var_start <= 0;
else if (Var_start == START_DELAY)
Var_start <= Var_start;
else
Var_start <= Var_start + 1;
always @ (posedge BIT_CLK)
if (!Reset_Ready)
Wait_for_BITCLK <= 0;
else if (Wait_for_BITCLK == WAIT_FOR_BITCLK_DELAY)
Wait_for_BITCLK <= Wait_for_BITCLK;
else
Wait_for_BITCLK <= Wait_for_BITCLK + 1;
// RESET is 0 until the start delay is over
assign RESET = (Var_start == START_DELAY) ? 1:0;
always @ (posedge BIT_CLK)
Reset_Ready <= (Var_start == START_DELAY) ? 1:0;
// DONE
always @ (posedge SYSCLK)
if (StC != Load)
Frame_Done_reg <= 0;
else
Frame_Done_reg <= {Frame_Done_reg[1:0], 1'b1};
assign DONE = (Frame_Done_reg[0]&Frame_Done_reg[1]&~(Frame_Done_reg[2])) ? 1:0;
// Increment is incremeneted to 256 and then set to 1. Increment is reset to 0 only when a RESET occurs
always @ (posedge BIT_CLK)
if (StC == Idle)
Increment <= 0;
else if ((StN == Load) || (StN == Send))
if (Increment == 256)
Increment <= 1;
else
Increment <= Increment +1 ;
// SYNC will have (12,288MHz / 256) = 48KHz frequency & 20.8us period. SYNC is active while Slot0 is being sent only = for 16 BIT_CLKs
assign SYNC = (((Increment < 16)&&(Increment > 0)) || (StN == Load)) ? 1:0;
// Saving the data from SDATA_IN into Data_reg_in & cleaning Data_reg_in if a reset occurs. Data_reg_in must be shifted during the Load stat as well
/*always @ (posedge BIT_CLK)
if (Var_start < START_DELAY - 1)
Data_reg_in <= 0;
else
Data_reg_in[255:0] <= {Data_reg_in[254:0], SDATA_IN};
*/
// Data_reg_out being loaded with a new frame and shifted each BIT_CLK to be sent on SDATA_OUT
always @ (posedge BIT_CLK)
if (StN == Load)
Data_reg_out <= {Slot0_in, Slot1_in, Slot2_in, Slot3_in, Slot4_in, Slot5_in, Slot6_in, Slot7_in, Slot8_in, Slot9_in, Slot10_in, Slot11_in, Slot12_in};
else
Data_reg_out [255:0] <= {Data_reg_out[254:0], 1'b0};
// State machine
always @ (posedge BIT_CLK or posedge SYSTEM_RESET)
if (SYSTEM_RESET)
StC <= Idle;
else
StC <= StN;
always @ *
begin
StN <= StC;
case (StC)
Idle: if ((!SYSTEM_RESET) && (Wait_for_BITCLK == WAIT_FOR_BITCLK_DELAY)) StN <= Wait_until_Start;
Wait_until_Start: if (Reset_Ready) StN <= Load;
Load: StN <= Send;
Send: if (Increment == 256) StN <= Load;
default: StN <= Idle;
endcase
end
assign SDATA_OUT = Data_reg_out[255];
/*always @ (posedge SYSCLK) begin
if (StC == Load)
begin
Slot0_out <= Data_reg_in[255:240];
Slot1_out <= Data_reg_in[239:220];
Slot2_out <= Data_reg_in[219:200];
Slot3_out <= Data_reg_in[199:180];
Slot4_out <= Data_reg_in[179:160];
Slot5_out <= Data_reg_in[159:140];
Slot6_out <= Data_reg_in[139:120];
Slot7_out <= Data_reg_in[119:100];
Slot8_out <= Data_reg_in[99:80];
Slot9_out <= Data_reg_in[79:60];
Slot10_out <= Data_reg_in[59:40];
Slot11_out <= Data_reg_in[39:20];
Slot12_out <= Data_reg_in[19:0];
end
end*/
endmodule