5
\$\begingroup\$

I am trying to get audio output from Atlys board (uses LM4550 audio codec). I got the ac97_controller.v core file which generates the serial o/p for the codec. It takes slots as inputs and puts them into the frames and transmits to the codec, at the same time it takes serial input from codec, extracts the slots and give those at output. I only want to send a square wave and i wrote top module for that. It sends the square wave audio PCM samples(2's complement and 18 bit). I also wrote logic to unmute the headphone & line_out o/p. Even post-route simulation looks perfect. But when i download it to Atlys board, it doesn't work. Can anybody tell what might be the problem. Thanks in Advance.

P.S. I checked the audio codec with demo project for AC97 from www.digilentinc.com and it works, the file ac97_controller is in there.

my code:

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

Controller ip:

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
\$\endgroup\$
1
  • \$\begingroup\$ Where exactly did you download the project from? \$\endgroup\$
    – user13719
    Oct 2, 2012 at 20:54

2 Answers 2

1
\$\begingroup\$

One possibility to consider: RS-232 cables come in two varieties, one with a crossover of certain wires and one without. You may need to determine which of these two varieties you're using, and then try again with the other variety.

\$\endgroup\$
0
\$\begingroup\$

I think you have to synchronize the loading of the data slot with the SYNC signal from the AC97. Also you need to wait until the codec is ready before sending it data. The codec sends a ready signal in bit 15 of slot0.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.