diff --git a/tridoracpu/tridoracpu.srcs/Arty-A7-35-Master.xdc b/tridoracpu/tridoracpu.srcs/Arty-A7-35-Master.xdc
index 7c62767..2a33ae0 100644
--- a/tridoracpu/tridoracpu.srcs/Arty-A7-35-Master.xdc
+++ b/tridoracpu/tridoracpu.srcs/Arty-A7-35-Master.xdc
@@ -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]
diff --git a/tridoracpu/tridoracpu.srcs/tdraudio.v b/tridoracpu/tridoracpu.srcs/tdraudio.v
new file mode 100644
index 0000000..dbd0dc3
--- /dev/null
+++ b/tridoracpu/tridoracpu.srcs/tdraudio.v
@@ -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
diff --git a/tridoracpu/tridoracpu.srcs/top.v b/tridoracpu/tridoracpu.srcs/top.v
index 00066fe..81d236b 100644
--- a/tridoracpu/tridoracpu.srcs/top.v
+++ b/tridoracpu/tridoracpu.srcs/top.v
@@ -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,
diff --git a/tridoracpu/tridoracpu.xpr b/tridoracpu/tridoracpu.xpr
index 36b5512..c5b003f 100644
--- a/tridoracpu/tridoracpu.xpr
+++ b/tridoracpu/tridoracpu.xpr
@@ -111,7 +111,7 @@
-
+
@@ -142,7 +142,7 @@
-
+
@@ -173,14 +173,14 @@
-
+
-
+
@@ -205,6 +205,13 @@
+
+
+
+
+
+
+