module DAC_IF ( i_Clk, // 21.47727[MHz] i_nReset, i_Audio, // 10-bit audio data o_DacClk, o_DacLso, o_DacRso, o_DacWdck ); input i_Clk; input i_nReset; input [ 9:0] i_Audio; // 10-bit FC audio data // Audio DAC uPD6376 output o_DacClk, o_DacLso, o_DacRso, o_DacWdck; // DAC reg [3:0] r_ProceedDac; reg [20:0] r_DacState; reg r_DacClk; reg r_DacWdck; reg [15:0] r_DacLatch; // sample latch & shift register reg [15:0] r_DacSample; // average of 21 samples /*----------------------------------------------------------------------------------- [proceed dac] -----------------------------------------------------------------------------------*/ always @(posedge i_Clk or negedge i_nReset) begin if (!i_nReset) r_ProceedDac <= 1; else r_ProceedDac <= {r_ProceedDac[2:0], r_ProceedDac[3]}; end /*----------------------------------------------------------------------------------- [audio dac] -----------------------------------------------------------------------------------*/ // state machine (operates at 5[MHz]) // 00-15: output bits 0-15 // 16-20: wait 5 clock for dac output to become valid always @(posedge i_Clk or negedge i_nReset) begin if (!i_nReset) r_DacState <= 0; else if (!r_DacState) r_DacState <= 1; else if (r_ProceedDac[3]) r_DacState <= { r_DacState[19:0], r_DacState[20] }; end // DacClk always @(posedge i_Clk or negedge i_nReset) begin if (!i_nReset) r_DacClk <= 0; else r_DacClk <= r_ProceedDac[1] | r_ProceedDac[2]; end // DacWdck always @(posedge i_Clk or negedge i_nReset) begin if (!i_nReset) r_DacWdck <= 0; else if (~r_DacWdck & r_DacState[4] & r_ProceedDac[3]) r_DacWdck <= 1; else if (r_DacWdck & r_DacState[15] & r_ProceedDac[3]) r_DacWdck <= 0; end // DacSample always @(posedge i_Clk or negedge i_nReset) begin if (!i_nReset) r_DacSample <= 0; else if (r_ProceedDac[3]) begin if (r_DacState[20]) r_DacSample <= { 6'h0, i_Audio }; else r_DacSample <= r_DacSample + { 6'h0, i_Audio }; end end // DacLatch always @(posedge i_Clk or negedge i_nReset) begin if (!i_nReset) r_DacLatch <= 0; else if (r_DacState[20] & r_ProceedDac[3]) r_DacLatch <= { ~r_DacSample[15], r_DacSample[14:0] }; else if ((|r_DacState[15:0]) & r_ProceedDac[3]) r_DacLatch <= { r_DacLatch[14:0], 1'b0 }; end assign o_DacClk = r_DacClk; assign o_DacLso = r_DacLatch[15]; assign o_DacRso = r_DacLatch[15]; assign o_DacWdck = r_DacWdck; endmodule