mirror of
https://github.com/MiSTer-devel/MacPlus_MiSTer.git
synced 2025-02-20 05:29:03 +00:00
158 lines
2.1 KiB
Verilog
158 lines
2.1 KiB
Verilog
|
|
module audio_out
|
|
#(
|
|
parameter CLK_RATE = 50000000
|
|
)
|
|
(
|
|
input reset,
|
|
input clk,
|
|
|
|
//0 - 48KHz, 1 - 96KHz
|
|
input sample_rate,
|
|
|
|
input [15:0] left_in,
|
|
input [15:0] right_in,
|
|
|
|
// I2S
|
|
output i2s_bclk,
|
|
output i2s_lrclk,
|
|
output i2s_data,
|
|
|
|
// SPDIF
|
|
output spdif,
|
|
|
|
// Sigma-Delta DAC
|
|
output dac_l,
|
|
output dac_r
|
|
);
|
|
|
|
localparam AUDIO_RATE = 48000;
|
|
localparam AUDIO_DW = 16;
|
|
|
|
localparam CE_RATE = AUDIO_RATE*AUDIO_DW*8;
|
|
localparam FILTER_DIV = (CE_RATE/(AUDIO_RATE*32))-1;
|
|
|
|
wire [31:0] real_ce = sample_rate ? {CE_RATE[30:0],1'b0} : CE_RATE[31:0];
|
|
|
|
reg mclk_ce;
|
|
always @(posedge clk) begin
|
|
reg [31:0] cnt;
|
|
|
|
mclk_ce <= 0;
|
|
cnt = cnt + real_ce;
|
|
if(cnt >= CLK_RATE) begin
|
|
cnt = cnt - CLK_RATE;
|
|
mclk_ce <= 1;
|
|
end
|
|
end
|
|
|
|
reg i2s_ce;
|
|
always @(posedge clk) begin
|
|
reg div;
|
|
i2s_ce <= 0;
|
|
if(mclk_ce) begin
|
|
div <= ~div;
|
|
i2s_ce <= div;
|
|
end
|
|
end
|
|
|
|
reg lpf_ce;
|
|
always @(posedge clk) begin
|
|
integer div;
|
|
lpf_ce <= 0;
|
|
if(mclk_ce) begin
|
|
div <= div + 1;
|
|
if(div == FILTER_DIV) begin
|
|
div <= 0;
|
|
lpf_ce <= 1;
|
|
end
|
|
end
|
|
end
|
|
|
|
i2s i2s
|
|
(
|
|
.reset(reset),
|
|
|
|
.clk(clk),
|
|
.ce(i2s_ce),
|
|
|
|
.sclk(i2s_bclk),
|
|
.lrclk(i2s_lrclk),
|
|
.sdata(i2s_data),
|
|
|
|
.left_chan(al),
|
|
.right_chan(ar)
|
|
);
|
|
|
|
spdif toslink
|
|
(
|
|
.rst_i(reset),
|
|
|
|
.clk_i(clk),
|
|
.bit_out_en_i(mclk_ce),
|
|
|
|
.sample_i({ar,al}),
|
|
.spdif_o(spdif)
|
|
);
|
|
|
|
sigma_delta_dac #(15) sd_l
|
|
(
|
|
.CLK(clk),
|
|
.RESET(reset),
|
|
.DACin({~al[15], al[14:0]}),
|
|
.DACout(dac_l)
|
|
);
|
|
|
|
sigma_delta_dac #(15) sd_r
|
|
(
|
|
.CLK(clk),
|
|
.RESET(reset),
|
|
.DACin({~ar[15], ar[14:0]}),
|
|
.DACout(dac_r)
|
|
);
|
|
|
|
wire [15:0] al, ar;
|
|
lpf_aud lpf_l
|
|
(
|
|
.CLK(clk),
|
|
.CE(lpf_ce),
|
|
.IDATA(left_in),
|
|
.ODATA(al)
|
|
);
|
|
|
|
lpf_aud lpf_r
|
|
(
|
|
.CLK(clk),
|
|
.CE(lpf_ce),
|
|
.IDATA(right_in),
|
|
.ODATA(ar)
|
|
);
|
|
|
|
endmodule
|
|
|
|
module lpf_aud
|
|
(
|
|
input CLK,
|
|
input CE,
|
|
input [15:0] IDATA,
|
|
output reg [15:0] ODATA
|
|
);
|
|
|
|
reg [511:0] acc;
|
|
reg [20:0] sum;
|
|
|
|
always @(*) begin
|
|
integer i;
|
|
sum = 0;
|
|
for (i = 0; i < 32; i = i+1) sum = sum + {{5{acc[(i*16)+15]}}, acc[i*16 +:16]};
|
|
end
|
|
|
|
always @(posedge CLK) begin
|
|
if(CE) begin
|
|
acc <= {acc[495:0], IDATA};
|
|
ODATA <= sum[20:5];
|
|
end
|
|
end
|
|
|
|
endmodule
|