// part of NeoGS project (c) 2007-2008 NedoPC
 
//
 
// sound_dac is a serializer of 16 bit data for TDA1543 DAC
 
// input is clock at 24 MHz and 16-bit parallel data
 
// the module generates strobe signal for data sender - load, indicating when it loaded new portion of data,
 
// and allowing sender to begin preparing new data. dac_leftright is also to be used by sender (by locking it
 
// when load is 1).
 
//
 
// dac_clock is symmetrical clock at 1/10 of input clock (2.4 MHz)
 
// load is positive 1 clock cycle pulse informing that new data has just loaded
 
 
 
module sound_dac(
 
        clock,         // input clock (24 MHz)
 
 
 
        dac_clock,     // clock to DAC
 
        dac_leftright, // left-right signal to DAC (0 - left, 1 - right)
 
        dac_data,      // data to DAC
 
 
 
        load,          // output indicating cycle when new data loaded from datain bus
 
 
 
        datain         // input 16-bit bus
 
);
 
 
 
        input clock;
 
 
 
        output dac_clock;
 
 
 
        output dac_leftright;
 
 
 
        output dac_data;
 
 
 
        output reg load;
 
 
 
 
 
        input [15:0] datain;
 
 
 
        reg [16:0] data; // internal shift register
 
 
 
        reg [2:0] fifth; // divide by 5
 
        reg [6:0] sync; // sync[0] - dac_clock
 
                        // sync[6] - dac_leftright
 
 
 
        wire load_int;
 
 
 
 
 
 
 
        // for simulation purposes
 
        initial
 
        begin
 
                fifth <= 0;
 
                sync <= 0;
 
                data <= 0;
 
                load <= 0;
 
        end
 
 
 
 
 
        // divide input clock by 5
 
        always @(posedge clock)
 
        begin
 
                if( fifth[2] )
 
                        fifth <= 3'b000;
 
                else
 
                        fifth <= fifth + 3'd1;
 
        end
 
 
 
        // divide further to get dac_clock and dac_leftright
 
        always @(posedge clock)
 
        begin
 
                if( fifth[2] )  sync <= sync + 7'd1;
 
        end
 
 
 
 
 
        // load signal generation
 
        assign load_int = fifth[2] & (&sync[5:0]);
 
 
 
        always @(posedge clock)
 
        begin
 
                        load <= load_int;
 
        end
 
 
 
        // loading and shifting data
 
        always @(posedge clock)
 
        begin
 
                if( fifth[2] && sync[0] )
 
                begin
 
                        if( load_int )
 
                                data[15:0] <= datain;
 
                        else
 
                                data[15:0] <= { data[14:0], 1'b0 }; // MSB first
 
 
 
                        data[16] <= data[15];
 
                end
 
        end
 
 
 
        assign dac_leftright = sync[6];
 
        assign dac_clock = sync[0];
 
        assign dac_data  = data[16];
 
 
 
endmodule