tdraudio: implement multiple channels
This commit is contained in:
parent
a73fad5786
commit
c354bb8cb8
2 changed files with 72 additions and 20 deletions
|
|
@ -1,27 +1,23 @@
|
||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
module tdraudio #(DATA_WIDTH=32) (
|
// waveform generator module (only pulse wave for now)
|
||||||
|
module wavegen #(DATA_WIDTH=32, CLOCK_DIV_WIDTH=22, AMP_WIDTH=16) (
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire reset,
|
input wire reset,
|
||||||
input wire [3:0] reg_sel,
|
input wire [1:0] reg_sel,
|
||||||
output wire [DATA_WIDTH-1:0] rd_data,
|
output wire [DATA_WIDTH-1:0] rd_data,
|
||||||
input wire [DATA_WIDTH-1:0] wr_data,
|
input wire [DATA_WIDTH-1:0] wr_data,
|
||||||
input wire rd_en,
|
input wire rd_en,
|
||||||
input wire wr_en,
|
input wire wr_en,
|
||||||
|
|
||||||
output wire pdm_out,
|
output wire [AMP_WIDTH-1:0] amp_val,
|
||||||
output wire gain_sel,
|
output wire running
|
||||||
output wire shutdown_n
|
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam CLOCK_DIV_WIDTH = 22;
|
|
||||||
localparam AMP_WIDTH = 16;
|
|
||||||
|
|
||||||
localparam TDRAU_REG_CTL = 0; /* control register */
|
localparam TDRAU_REG_CTL = 0; /* control register */
|
||||||
localparam TDRAU_REG_CLK = 1; /* clock divider register */
|
localparam TDRAU_REG_CLK = 1; /* clock divider register */
|
||||||
localparam TDRAU_REG_AMP = 2; /* amplitude (volume) register */
|
localparam TDRAU_REG_AMP = 2; /* amplitude (volume) register */
|
||||||
|
|
||||||
wire audio_out;
|
|
||||||
reg channel_enable;
|
reg channel_enable;
|
||||||
reg [CLOCK_DIV_WIDTH-1:0] clock_div;
|
reg [CLOCK_DIV_WIDTH-1:0] clock_div;
|
||||||
reg [CLOCK_DIV_WIDTH-1:0] div_count;
|
reg [CLOCK_DIV_WIDTH-1:0] div_count;
|
||||||
|
|
@ -29,12 +25,10 @@ module tdraudio #(DATA_WIDTH=32) (
|
||||||
reg [AMP_WIDTH-1:0] amp_start;
|
reg [AMP_WIDTH-1:0] amp_start;
|
||||||
reg [AMP_WIDTH-1:0] amp_out;
|
reg [AMP_WIDTH-1:0] amp_out;
|
||||||
|
|
||||||
reg [AMP_WIDTH:0] deltasigma_acc;
|
//assign rd_data = {{DATA_WIDTH-8-CLOCK_DIV_WIDTH{1'b0}}, div_count, {7{1'b0}}, channel_enable};
|
||||||
|
assign rd_data = {8'b0, amp_start, {7{1'b0}}, channel_enable};
|
||||||
assign pdm_out = audio_out;
|
assign amp_val = amp_out;
|
||||||
assign rd_data = {{DATA_WIDTH-8-CLOCK_DIV_WIDTH{1'b0}}, div_count, {7{1'b0}}, channel_enable};
|
assign running = channel_enable;
|
||||||
assign gain_sel = 1; // gain select: 0 -> 12dB, 1 -> 6dB
|
|
||||||
assign shutdown_n = channel_enable;
|
|
||||||
|
|
||||||
/* channel enable flag */
|
/* channel enable flag */
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
|
|
@ -101,6 +95,64 @@ module tdraudio #(DATA_WIDTH=32) (
|
||||||
// because div_count will become zero
|
// because div_count will become zero
|
||||||
amp_phase <= 1;
|
amp_phase <= 1;
|
||||||
end
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module tdraudio #(DATA_WIDTH=32) (
|
||||||
|
input wire clk,
|
||||||
|
input wire reset,
|
||||||
|
input wire [6:0] io_addr,
|
||||||
|
output wire [DATA_WIDTH-1:0] rd_data,
|
||||||
|
input wire [DATA_WIDTH-1:0] wr_data,
|
||||||
|
input wire rd_en,
|
||||||
|
input wire wr_en,
|
||||||
|
|
||||||
|
output wire pdm_out,
|
||||||
|
output wire gain_sel,
|
||||||
|
output wire shutdown_n
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam CLOCK_DIV_WIDTH = 22;
|
||||||
|
localparam AMP_WIDTH = 16;
|
||||||
|
|
||||||
|
wire chan_sel = io_addr[6:2];
|
||||||
|
wire [1:0] reg_sel = io_addr[1:0];
|
||||||
|
|
||||||
|
wire [AMP_WIDTH-1:0] chan0_amp;
|
||||||
|
wire [DATA_WIDTH-1:0] chan0_rd_data;
|
||||||
|
wire chan0_running;
|
||||||
|
wire chan0_sel = chan_sel == 0;
|
||||||
|
wire chan0_rd_en = chan0_sel && rd_en;
|
||||||
|
wire chan0_wr_en = chan0_sel && wr_en;
|
||||||
|
|
||||||
|
wire [AMP_WIDTH-1:0] chan1_amp;
|
||||||
|
wire [DATA_WIDTH-1:0] chan1_rd_data;
|
||||||
|
wire chan1_running;
|
||||||
|
wire chan1_sel = chan_sel == 1;
|
||||||
|
wire chan1_rd_en = chan1_sel && rd_en;
|
||||||
|
wire chan1_wr_en = chan1_sel && wr_en;
|
||||||
|
|
||||||
|
wire running = chan0_running || chan1_running;
|
||||||
|
|
||||||
|
assign rd_data = chan0_sel ? chan0_rd_data :
|
||||||
|
chan1_sel ? chan1_rd_data :
|
||||||
|
{DATA_WIDTH{1'b1}};
|
||||||
|
|
||||||
|
wavegen chan0(clk, reset, reg_sel,
|
||||||
|
chan0_rd_data, wr_data,
|
||||||
|
chan0_rd_en, chan0_wr_en,
|
||||||
|
chan0_amp, chan0_running);
|
||||||
|
|
||||||
|
wavegen chan1(clk, reset, reg_sel,
|
||||||
|
chan1_rd_data, wr_data,
|
||||||
|
chan1_rd_en, chan1_wr_en,
|
||||||
|
chan1_amp, chan1_running);
|
||||||
|
|
||||||
|
reg [AMP_WIDTH:0] deltasigma_acc; // one extra bit
|
||||||
|
wire [AMP_WIDTH:0] amp_sum = chan0_amp + chan1_amp; // also one overflow bit here
|
||||||
|
wire [AMP_WIDTH-1:0] amp_sum_scaled = amp_sum[AMP_WIDTH:1]; // shifted right to scale down
|
||||||
|
assign gain_sel = 1; // gain select: 0 -> 12dB, 1 -> 6dB
|
||||||
|
|
||||||
|
assign shutdown_n = running;
|
||||||
|
|
||||||
/* delta-sigma DAC */
|
/* delta-sigma DAC */
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
|
|
@ -108,10 +160,10 @@ module tdraudio #(DATA_WIDTH=32) (
|
||||||
if(reset)
|
if(reset)
|
||||||
deltasigma_acc <= 0;
|
deltasigma_acc <= 0;
|
||||||
else
|
else
|
||||||
if (channel_enable)
|
if (running)
|
||||||
deltasigma_acc <= deltasigma_acc[AMP_WIDTH-1:0] + amp_out;
|
deltasigma_acc <= deltasigma_acc[AMP_WIDTH-1:0] + amp_sum_scaled;
|
||||||
end
|
end
|
||||||
|
|
||||||
/* 1-bit audio output */
|
/* 1-bit audio output */
|
||||||
assign audio_out = deltasigma_acc[AMP_WIDTH];
|
assign pdm_out = deltasigma_acc[AMP_WIDTH];
|
||||||
endmodule
|
endmodule
|
||||||
|
|
@ -248,7 +248,7 @@ module top(
|
||||||
assign tdraudio_wr_data = mem_write_data;
|
assign tdraudio_wr_data = mem_write_data;
|
||||||
|
|
||||||
tdraudio tdraudio0(`clock, ~rst,
|
tdraudio tdraudio0(`clock, ~rst,
|
||||||
mem_addr[3:0],
|
mem_addr[6:0],
|
||||||
tdraudio_rd_data,
|
tdraudio_rd_data,
|
||||||
tdraudio_wr_data,
|
tdraudio_wr_data,
|
||||||
tdraudio_rd_en,
|
tdraudio_rd_en,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue