163 lines
3.6 KiB
Verilog
163 lines
3.6 KiB
Verilog
`timescale 1ns / 1ps
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
// Company:
|
|
// Engineer:
|
|
//
|
|
// Create Date: 19:26:11 07/23/2010
|
|
// Design Name:
|
|
// Module Name: dac_test
|
|
// Project Name:
|
|
// Target Devices:
|
|
// Tool versions:
|
|
// Description:
|
|
//
|
|
// Dependencies:
|
|
//
|
|
// Revision:
|
|
// Revision 0.01 - File Created
|
|
// Additional Comments:
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
module dac(
|
|
input clkin,
|
|
input sysclk,
|
|
input we,
|
|
input[10:0] pgm_address,
|
|
input[7:0] pgm_data,
|
|
input[7:0] volume,
|
|
input vol_latch,
|
|
input play,
|
|
input reset,
|
|
output sdout,
|
|
output lrck,
|
|
output mclk,
|
|
output sclk,
|
|
output DAC_STATUS
|
|
);
|
|
|
|
reg[8:0] dac_address_r;
|
|
wire[8:0] dac_address = dac_address_r;
|
|
|
|
wire[31:0] dac_data;
|
|
assign DAC_STATUS = dac_address_r[8];
|
|
reg[7:0] vol_reg;
|
|
reg[7:0] vol_target_reg;
|
|
reg[1:0] vol_latch_reg;
|
|
reg vol_valid;
|
|
reg[2:0] sysclk_sreg;
|
|
wire sysclk_rising = (sysclk_sreg[2:1] == 2'b01);
|
|
|
|
reg [25:0] interpol_count;
|
|
|
|
always @(posedge clkin) begin
|
|
sysclk_sreg <= {sysclk_sreg[1:0], sysclk};
|
|
end
|
|
|
|
dac_buf snes_dac_buf (
|
|
.clka(clkin),
|
|
.wea(~we), // Bus [0 : 0]
|
|
.addra(pgm_address), // Bus [10 : 0]
|
|
.dina(pgm_data), // Bus [7 : 0]
|
|
.clkb(clkin),
|
|
.addrb(dac_address), // Bus [8 : 0]
|
|
.doutb(dac_data)); // Bus [31 : 0]
|
|
|
|
reg [8:0] cnt;
|
|
reg [15:0] smpcnt;
|
|
reg [1:0] samples;
|
|
reg [15:0] smpshift;
|
|
|
|
assign mclk = cnt[2]; // mclk = clk/8
|
|
assign lrck = cnt[8]; // lrck = mclk/128
|
|
assign sclk = cnt[3]; // sclk = lrck*32
|
|
|
|
reg [2:0] lrck_sreg;
|
|
reg [2:0] sclk_sreg;
|
|
wire lrck_rising = (lrck_sreg[1:0] == 2'b01);
|
|
wire lrck_falling = (lrck_sreg[1:0] == 2'b10);
|
|
|
|
wire sclk_rising = (sclk_sreg[1:0] == 2'b01);
|
|
wire sclk_falling = (sclk_sreg[1:0] == 2'b10);
|
|
|
|
wire vol_latch_rising = (vol_latch_reg[1:0] == 2'b01);
|
|
reg sdout_reg;
|
|
assign sdout = sdout_reg;
|
|
|
|
reg [1:0] reset_sreg;
|
|
wire reset_rising = (reset_sreg[1:0] == 2'b01);
|
|
|
|
reg play_r;
|
|
|
|
initial begin
|
|
cnt = 9'h100;
|
|
smpcnt = 16'b0;
|
|
lrck_sreg = 2'b11;
|
|
sclk_sreg = 1'b0;
|
|
dac_address_r = 10'b0;
|
|
vol_valid = 1'b0;
|
|
vol_latch_reg = 1'b0;
|
|
vol_reg = 8'h0;
|
|
vol_target_reg = 8'hff;
|
|
samples <= 2'b00;
|
|
end
|
|
|
|
always @(posedge clkin) begin
|
|
if(reset_rising) begin
|
|
dac_address_r <= 0;
|
|
interpol_count <= 0;
|
|
end else if(sysclk_rising) begin
|
|
if(interpol_count > 59378938) begin
|
|
interpol_count <= interpol_count + 122500 - 59501439;
|
|
dac_address_r <= dac_address_r + play_r;
|
|
end else begin
|
|
interpol_count <= interpol_count + 122500;
|
|
end
|
|
end
|
|
end
|
|
|
|
always @(posedge clkin) begin
|
|
cnt <= cnt + 1;
|
|
lrck_sreg <= {lrck_sreg[1:0], lrck};
|
|
sclk_sreg <= {sclk_sreg[1:0], sclk};
|
|
vol_latch_reg <= {vol_latch_reg[0], vol_latch};
|
|
play_r <= play;
|
|
reset_sreg <= {reset_sreg[0], reset};
|
|
end
|
|
|
|
always @(posedge clkin) begin
|
|
if (vol_latch_rising) begin
|
|
vol_valid <= 1'b1;
|
|
end
|
|
else if(vol_valid) begin
|
|
vol_target_reg <= volume;
|
|
vol_valid <= 1'b0;
|
|
end
|
|
end
|
|
|
|
// ramp volume only every 4 samples
|
|
always @(posedge clkin) begin
|
|
if (lrck_rising && &samples[1:0]) begin
|
|
if(vol_reg > vol_target_reg)
|
|
vol_reg <= vol_reg - 1;
|
|
else if(vol_reg < vol_target_reg)
|
|
vol_reg <= vol_reg + 1;
|
|
end
|
|
end
|
|
|
|
always @(posedge clkin) begin
|
|
if (sclk_falling) begin
|
|
smpcnt <= smpcnt + 1;
|
|
sdout_reg <= smpshift[15];
|
|
if (lrck_rising) begin // right channel
|
|
smpshift <= (({16'h0, dac_data[31:16]^16'h8000} * vol_reg) >> 8) ^ 16'h8000;
|
|
samples <= samples + 1;
|
|
end else if (lrck_falling) begin // left channel
|
|
smpshift <= (({16'h0, dac_data[15:0]^16'h8000} * vol_reg) >> 8) ^ 16'h8000;
|
|
end else begin
|
|
smpshift <= {smpshift[14:0], 1'b0};
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule
|