tdraudio: first step of implementing a sound generator

This commit is contained in:
slederer 2025-09-23 23:39:04 +02:00
parent f79d7d622a
commit d5888861d3
4 changed files with 119 additions and 8 deletions

View file

@ -70,10 +70,10 @@ set_property -dict {PACKAGE_PIN V14 IOSTANDARD LVCMOS33} [get_ports VGA_VS_O]
#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { jc[7] }]; #IO_L23N_T3_A02_D18_14 Sch=jc_n[4]
## Pmod Header JD
#set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { jd[0] }]; #IO_L11N_T1_SRCC_35 Sch=jd[1]
#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { jd[1] }]; #IO_L12N_T1_MRCC_35 Sch=jd[2]
set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { amp2_ain }]; #IO_L11N_T1_SRCC_35 Sch=jd[1]
set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { amp2_gain }]; #IO_L12N_T1_MRCC_35 Sch=jd[2]
#set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { jd[2] }]; #IO_L13P_T2_MRCC_35 Sch=jd[3]
#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { jd[3] }]; #IO_L13N_T2_MRCC_35 Sch=jd[4]
set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { amp2_shutdown_n }]; #IO_L13N_T2_MRCC_35 Sch=jd[4]
#set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { jd[4] }]; #IO_L14P_T2_SRCC_35 Sch=jd[7]
#set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { jd[5] }]; #IO_L14N_T2_SRCC_35 Sch=jd[8]
#set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { jd[6] }]; #IO_L15P_T2_DQS_35 Sch=jd[9]

View file

@ -0,0 +1,74 @@
`timescale 1ns / 1ps
module tdraudio #(DATA_WIDTH=32) (
input wire clk,
input wire reset,
input wire [3:0] reg_sel,
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_en,
output wire shutdown_n
);
localparam CLOCK_DIV_WIDTH = 22;
localparam TDRAU_REG_CTL = 0; /* control register */
localparam TDRAU_REG_CLK = 1; /* clock divider register */
reg audio_out;
reg channel_enable;
reg [CLOCK_DIV_WIDTH-1:0] clock_div;
reg [CLOCK_DIV_WIDTH-1:0] div_count;
assign pdm_out = audio_out;
assign rd_data = {{DATA_WIDTH-8-CLOCK_DIV_WIDTH{1'b0}}, div_count, {7{1'b0}}, channel_enable};
assign gain_en = 0;
assign shutdown_n = channel_enable;
/* channel enable flag */
always @(posedge clk)
begin
if(reset)
channel_enable <= 0;
else if (wr_en && (reg_sel == TDRAU_REG_CTL))
channel_enable <= wr_data[0];
end
/* clock divider register */
always @(posedge clk)
begin
if(reset)
clock_div <= 0;
else if (wr_en && (reg_sel == TDRAU_REG_CLK))
clock_div <= wr_data;
end
/* divider counter */
always @(posedge clk)
begin
if(channel_enable)
begin
if(div_count == 0) // reset counter if it reaches zero
div_count <= clock_div;
else
div_count <= div_count - 1; // else just decrement it
end
else
if (wr_en && (reg_sel == TDRAU_REG_CLK))
div_count <= 0; // set counter to zero whenever the clock divider is set
end
/* 1-bit audio output */
always @(posedge clk)
begin
if (reset)
audio_out <= 0;
else
if (channel_enable && (div_count == 0))
audio_out <= ~audio_out;
end
endmodule

View file

@ -10,6 +10,7 @@
//`define clock clk_1hz
`define ENABLE_VGAFB
`define ENABLE_MICROSD
`define ENABLE_TDRAUDIO
module top(
input wire clk,
@ -60,6 +61,13 @@ module top(
output wire sd_sck,
input wire sd_cd
`endif
`ifdef ENABLE_TDRAUDIO
,
output wire amp2_ain,
output wire amp2_gain,
output wire amp2_shutdown_n
`endif
);
reg clk_1hz;
@ -220,6 +228,7 @@ module top(
assign uart_tx_data = mem_write_data[7:0];
assign uart_rd_data = { {WIDTH-10{1'b1}}, uart_rx_avail, uart_tx_busy, uart_rx_data };
// interrupt controller
reg timer_tick;
reg[23:0] tick_count;
wire [1:0] irq_in = { timer_tick, uart_rx_avail };
@ -228,6 +237,25 @@ module top(
wire irqc_seten = mem_write_data[7];
wire irqc_cs = io_enable && (io_slot == 3);
`ifdef ENABLE_TDRAUDIO
wire [WIDTH-1:0] tdraudio_wr_data;
wire [WIDTH-1:0] tdraudio_rd_data;
wire tdraudio_rd_en, tdraudio_wr_en;
wire tdraudio_cs_en = io_enable && (io_slot == 4);
assign tdraudio_rd_en = tdraudio_cs_en && mem_read_enable;
assign tdraudio_wr_en = tdraudio_cs_en && mem_write_enable;
assign tdraudio_wr_data = mem_write_data;
tdraudio tdraudio0(`clock, ~rst,
mem_addr[3:0],
tdraudio_rd_data,
tdraudio_wr_data,
tdraudio_rd_en,
tdraudio_wr_en,
amp2_ain, amp2_gain, amp2_shutdown_n);
`endif
assign io_rd_data = (io_slot == 0) ? uart_rd_data :
`ifdef ENABLE_MICROSD
(io_slot == 1) ? spi_rd_data :
@ -236,7 +264,9 @@ module top(
(io_slot == 2) ? fb_rd_data :
`endif
(io_slot == 3) ? irqc_rd_data:
`ifdef ENABLE_TDRAUDIO
(io_slot == 4) ? tdraudio_rd_data:
`endif
-1;
buart #(.CLKFREQ(`clkfreq)) uart0(`clock, rst,

View file

@ -111,7 +111,7 @@
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/stack.v">
<File Path="$PSRCDIR/stack.v" Mode="RelativeOnly">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
@ -142,7 +142,7 @@
</FileInfo>
</File>
<File Path="$PSRCDIR/testbench.v"/>
<File Path="$PPRDIR/rom.mem">
<File Path="$PPRDIR/rom.mem" Mode="RelativeOnly">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
@ -173,14 +173,14 @@
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/bram_tdp.v">
<File Path="$PSRCDIR/bram_tdp.v" Mode="RelativeOnly">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/palette.v">
<File Path="$PSRCDIR/palette.v" Mode="RelativeOnly">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
@ -205,6 +205,13 @@
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/tdraudio.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="top"/>